@@ -19,8 +19,9 @@ var arguments := { }
1919
2020var _current_unload_type := - 1
2121var _url_normalization_regex := RegExpGroup .compile (
22- "^(?<prefix>user:\\ / \\ /|res:\\ / \\ /|\\ .*?\\ /+)(?<url >.*) \ \ .(?<extension>( t?res|bbcode)) " ,
22+ r "^(?<prefix>user:\/\ / |res:\/\ / |\. *?\/ +)#? (?<course >.*?) \/ (?<lesson>.*) \. (?<extension>t?res|bbcode)(?<practice>#P[0-9]+)? " ,
2323)
24+ var _practice_regex := RegEx .create_from_string ("#P[0-9]+" )
2425var _lesson_cache := { }
2526
2627
@@ -136,29 +137,54 @@ func navigate_to(metadata: String) -> void:
136137 if not regex_result :
137138 push_error ("`%s ` is not a valid resource or bbcode path" % [metadata ])
138139 return
140+
139141 var normalized := NormalizedUrl .new (regex_result )
140-
141- if not normalized .path :
142+
143+ var course_index := CourseIndexPaths .get_course_index_instance (normalized .course_path )
144+ if not course_index :
145+ push_error ("'%s ' is not a valid course" % [normalized .course_path ])
146+ return
147+
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 )
154+ normalized = NormalizedUrl .new (regex_result )
155+
156+ if not normalized .lesson_path :
142157 push_error ("`%s ` is not a valid path" % metadata )
143158 return
144159
145- var file_path := normalized . get_file_path ( )
160+ var lesson_path := course_index . get_lesson_path_from_slug ( " %s . %s " % [ normalized . lesson_path , normalized . extension ] )
146161
147- var resource := get_navigation_resource (file_path )
148- if not (resource is BBCodeParser .ParseNode ):
149- push_error ("`%s ` is not a resource " % file_path )
162+ var lesson := get_navigation_resource (lesson_path )
163+ if not (lesson is BBCodeParser .ParseNode ):
164+ push_error ("`%s ` is not a lesson " % lesson_path )
150165 return
151166
152- history .push_back (file_path )
167+ var effective_path := lesson_path
168+ if normalized .practice_index > - 1 :
169+ var practice := BBCodeUtils .get_lesson_practice (lesson , normalized .practice_index )
170+ if not practice is BBCodeParser .ParseNode :
171+ push_error ("'%s ' does not have a practice at index '%s '" % [lesson_path , normalized .practice_index ])
172+ return
173+ effective_path += "#P%s " % [normalized .practice_index ]
174+
175+ history .push_back (effective_path )
153176 _push_javascript_state (normalized .get_web_url ())
154177
155178 emit_signal ("navigation_requested" )
156179
157180
158181func get_navigation_resource (resource_id : String ) -> BBCodeParser .ParseNode :
159- var is_lesson := resource_id .ends_with ("lesson.bbcode" )
160-
161- var bbcode_path := resource_id if is_lesson else resource_id .get_base_dir ().path_join ("lesson.bbcode" )
182+ var practice_index_match := _practice_regex .search (resource_id )
183+ var is_practice := practice_index_match != null
184+
185+ var bbcode_path := resource_id
186+ if is_practice :
187+ bbcode_path = bbcode_path .left (- practice_index_match .strings [0 ].length ())
162188
163189 var lesson_data : BBCodeParser .ParseNode = null
164190 if _lesson_cache .has (bbcode_path ):
@@ -183,18 +209,11 @@ func get_navigation_resource(resource_id: String) -> BBCodeParser.ParseNode:
183209 lesson_data = result .root .children [0 ]
184210 _lesson_cache [bbcode_path ] = lesson_data
185211
186- if is_lesson :
187- return lesson_data
188-
189- # If it's not a lesson, it's a practice. May support some other types in future.
190- var practice_count := BBCodeUtils .get_lesson_practice_count (lesson_data )
191- for i in practice_count :
192- var other_practice := BBCodeUtils .get_lesson_practice (lesson_data , i )
193- var other_practice_id := BBCodeUtils .get_practice_id (other_practice )
194- if other_practice_id == resource_id :
195- return other_practice
212+ 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 )
196215
197- return null
216+ return lesson_data
198217
199218
200219# Handle back requests
@@ -318,25 +337,41 @@ func _push_javascript_state(url: String) -> void:
318337
319338class NormalizedUrl :
320339 var protocol := ""
321- var path := ""
340+ var course_path := ""
341+ var lesson_path := ""
342+ var practice_index := - 1
322343 var extension := ""
323344
324345
325346 func _init (regex_result : RegExMatch ) -> void :
326347 protocol = regex_result .get_string ("prefix" )
327- path = regex_result .get_string ("url" )
348+ course_path = regex_result .get_string ("course" )
349+ lesson_path = regex_result .get_string ("lesson" )
328350 extension = regex_result .get_string ("extension" )
351+
352+ var practice_string := regex_result .get_string ("practice" )
353+ if practice_string :
354+ practice_index = int (practice_string .substr (2 ))
329355 if protocol in ["//" , "/" ]:
330356 protocol = "res://"
331357
332358
333359 func get_file_path () -> String :
334- return "%s%s .%s " % [protocol , path , extension ]
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 ]
363+ return file_path
335364
336365
337366 func get_web_url () -> String :
338- return "%s .%s " % [path , extension ]
367+ var url := "%s /%s .%s " % [course_path , lesson_path , extension ]
368+ if practice_index > - 1 :
369+ url += "#P%s " % [practice_index ]
370+ return url
339371
340372
341373 func _to_string () -> String :
342- return protocol + path
374+ var string := "%s%s /%s "
375+ if practice_index > - 1 :
376+ string += "#P%s " % [practice_index ]
377+ return string
0 commit comments