@@ -19,20 +19,24 @@ var arguments := { }
1919
2020var _current_unload_type := - 1
2121var _url_normalization_regex := RegExpGroup .compile (
22- r "^(?<prefix>user:\/\/ |res:\/\/ |\. *?\/ +)#?(?<course>.*?)\/ (?<lesson>.*)\. (?<extension>t?res|bbcode)(?<practice>#P[0-9]+)?" ,
22+ r "^(?<prefix>user:\/\/ |res:\/\/ |\. *?\/ +)#?(?<course>[^\/ ]+)\/ (?<lesson>[^\/ ]+)\/ ?(?<lesson_file>[^\. ]+\. [^\/ ]+)?\/ ?(?<practice>\$ .*)?" ,
23+ )
24+ var _slug_normalization_regex := RegExpGroup .compile (
25+ r "^#?(?<course>[^\/ ]+)\/ (?<lesson>[^\$ ]+)\/ ?(?<practice>\$ .*)?" ,
2326)
24- var _practice_regex := RegEx .create_from_string ("#P[0-9]+" )
2527var _lesson_cache := { }
2628
2729
2830func _init () -> void :
31+ CourseIndexPaths .build_all_practice_slugs .call_deferred ()
32+
2933 _parse_arguments ()
3034 if _js_available :
31- _on_init_setup_js ()
35+ _on_init_setup_js . call_deferred ()
3236 else :
3337 var initial_url : String = arguments .get ("file" , "" )
3438 if initial_url != "" :
35- navigate_to (initial_url )
39+ navigate_to . call_deferred (initial_url )
3640
3741
3842func _parse_arguments () -> void :
@@ -135,7 +139,10 @@ func navigate_to_welcome_screen() -> void:
135139func navigate_to (metadata : String ) -> void :
136140 var regex_result := _url_normalization_regex .search (metadata )
137141 if not regex_result :
138- push_error ("`%s ` is not a valid resource or bbcode path" % [metadata ])
142+ regex_result = _slug_normalization_regex .search (metadata )
143+
144+ if not regex_result :
145+ push_error ("`%s ` is not a valid bbcode or slug path" % [metadata ])
139146 return
140147
141148 var normalized := NormalizedUrl .new (regex_result )
@@ -145,47 +152,49 @@ func navigate_to(metadata: String) -> void:
145152 push_error ("'%s ' is not a valid course" % [normalized .course_path ])
146153 return
147154
148- # legacy practices support
149- var full_lesson_path := "%s .%s " % [normalized .lesson_path , normalized .extension ]
150- var alias := course_index .get_real_slug_from_slug (full_lesson_path )
151- if alias != full_lesson_path :
152- var new_path := "%s%s /%s " % [normalized .protocol , normalized .course_path , alias ]
153- regex_result = _url_normalization_regex .search (new_path )
155+ # legacy slugs support
156+ var legacy_path := normalized .lesson_path
157+ var lesson_slug := course_index .get_real_slug_from_slug (legacy_path )
158+ if lesson_slug != legacy_path :
159+ regex_result = _slug_normalization_regex .search ("%s /%s " % [course_index .get_course_id (), lesson_slug ])
154160 normalized = NormalizedUrl .new (regex_result )
155161
156- if not normalized .lesson_path :
157- push_error ("`%s ` is not a valid path" % metadata )
158- return
159-
160- var lesson_path := course_index .get_lesson_path_from_slug ("%s .%s " % [normalized .lesson_path , normalized .extension ])
162+ var lesson_path := course_index .get_lesson_path_from_slug (normalized .lesson_path )
161163
162164 var lesson := get_navigation_resource (lesson_path )
163165 if not (lesson is BBCodeParser .ParseNode ):
164166 push_error ("`%s ` is not a lesson" % lesson_path )
165167 return
166168
167- var effective_path := lesson_path
168- if normalized .practice_index > - 1 :
169- var practice := BBCodeUtils . get_lesson_practice ( lesson , normalized .practice_index )
169+ var effective_path := " %s / %s " % [ course_index . get_course_id (), normalized . lesson_path ]
170+ if normalized .practice_path != "" :
171+ var practice := course_index . get_practice_from_slug ( " %s /$ %s " % [ normalized . lesson_path , normalized .practice_path ] )
170172 if not practice is BBCodeParser .ParseNode :
171- push_error ("'%s ' does not have a practice at index '%s '" % [lesson_path , normalized .practice_index ])
173+ push_error ("'%s ' does not have a practice at slug '%s '" % [lesson_path , normalized .practice_path ])
172174 return
173- effective_path += "#P %s " % [normalized .practice_index ]
175+ effective_path += "/$ %s " % [normalized .practice_path ]
174176
175177 history .push_back (effective_path )
176- _push_javascript_state (normalized . get_web_url () )
178+ _push_javascript_state (effective_path )
177179
178- emit_signal ( " navigation_requested" )
180+ navigation_requested . emit ( )
179181
180182
181183func get_navigation_resource (resource_id : String ) -> BBCodeParser .ParseNode :
182- var practice_index_match := _practice_regex .search (resource_id )
183- var is_practice := practice_index_match != null
184+ var normalized_url_groups := _url_normalization_regex .search (resource_id )
185+ var is_slug := false
186+ if not normalized_url_groups :
187+ is_slug = true
188+ normalized_url_groups = _slug_normalization_regex .search (resource_id )
189+ var is_practice := not normalized_url_groups .get_string ("practice" ).is_empty ()
184190
185191 var bbcode_path := resource_id
186192 if is_practice :
187- bbcode_path = bbcode_path .left (- practice_index_match .strings [0 ].length ())
188-
193+ bbcode_path = bbcode_path .left (- (normalized_url_groups .get_end ("practice" )- normalized_url_groups .get_start ("practice" )+ 1 ))
194+ if is_slug :
195+ var course_index := CourseIndexPaths .get_course_index_instance (normalized_url_groups .get_string ("course" ))
196+ bbcode_path = course_index .get_lesson_path_from_slug (normalized_url_groups .get_string ("lesson" ).trim_suffix ("/" ))
197+
189198 var lesson_data : BBCodeParser .ParseNode = null
190199 if _lesson_cache .has (bbcode_path ):
191200 lesson_data = _lesson_cache [bbcode_path ]
@@ -210,9 +219,9 @@ func get_navigation_resource(resource_id: String) -> BBCodeParser.ParseNode:
210219 _lesson_cache [bbcode_path ] = lesson_data
211220
212221 if is_practice :
213- var practice_idx := int ( practice_index_match . strings [ 0 ]. substr ( 2 ))
214- return BBCodeUtils . get_lesson_practice ( lesson_data , practice_idx )
215-
222+ var course_index := CourseIndexPaths . get_course_index_instance ( normalized_url_groups . get_string ( "course" ))
223+ var lesson_slug := course_index . get_lesson_slug_from_path ( bbcode_path )
224+ return course_index . get_practice_from_slug ( " %s / %s " % [ lesson_slug , normalized_url_groups . get_string ( "practice" )])
216225 return lesson_data
217226
218227
@@ -283,7 +292,7 @@ func _on_init_setup_js() -> void:
283292 else ""
284293 )
285294 if url :
286- navigate_to ("res:// %s " % [ url ] )
295+ navigate_to (url )
287296
288297
289298# Handles user changing the url manually or pressing back
@@ -339,39 +348,43 @@ class NormalizedUrl:
339348 var protocol := ""
340349 var course_path := ""
341350 var lesson_path := ""
342- var practice_index := - 1
343- var extension := ""
351+ var practice_path := ""
352+ var lesson_file := ""
344353
345354
346355 func _init (regex_result : RegExMatch ) -> void :
347356 protocol = regex_result .get_string ("prefix" )
348357 course_path = regex_result .get_string ("course" )
349- lesson_path = regex_result .get_string ("lesson" )
350- extension = regex_result .get_string ("extension" )
358+ lesson_path = regex_result .get_string ("lesson" ).trim_suffix ("/" )
359+ practice_path = regex_result .get_string ("practice" ).substr (1 )
360+ lesson_file = regex_result .get_string ("lesson_file" )
351361
352- var practice_string := regex_result .get_string ("practice" )
353- if practice_string :
354- practice_index = int (practice_string .substr (2 ))
355362 if protocol in ["//" , "/" ]:
356363 protocol = "res://"
357364
358365
359- func get_file_path () -> String :
360- var file_path := "%s%s /%s .%s " % [protocol , course_path , lesson_path , extension ]
361- if practice_index > - 1 :
362- file_path += "#P" % [practice_index ]
366+ func get_file_path (with_practices : bool = false ) -> String :
367+ var file_path := "%s%s /%s " % [protocol , course_path , lesson_path ]
368+ if lesson_file != "" :
369+ file_path += "/%s " % [lesson_file ]
370+ if with_practices and practice_path != "" :
371+ file_path += "/$%s " % [practice_path ]
363372 return file_path
364373
365374
366375 func get_web_url () -> String :
367- var url := "%s /%s .%s " % [course_path , lesson_path , extension ]
368- if practice_index > - 1 :
369- url += "#P%s " % [practice_index ]
376+ var url := "%s /%s " % [course_path , lesson_path ]
377+ if lesson_file != "" :
378+ url += "/%s " % [lesson_file ]
379+ if practice_path != "" :
380+ url += "/$%s " % [practice_path ]
370381 return url
371382
372383
373384 func _to_string () -> String :
374- var string := "%s%s /%s "
375- if practice_index > - 1 :
376- string += "#P%s " % [practice_index ]
385+ var string := "%s%s /%s " % [protocol , course_path , lesson_path ]
386+ if lesson_file != "" :
387+ string += "/%s " % [lesson_file ]
388+ if practice_path != "" :
389+ string += "/$%s " % [practice_path ]
377390 return string
0 commit comments