Packages <<
Previous Next >> Parameters
URL
URL 參數解析過程
-
URL 解析函數: 程式中使用 RUR.permalink.parseUri(window.location.href)
來解析 URL。這個函數會將 URL 的查詢參數提取出來並存儲在 url_query.queryKey
解析的例子: 如果 URL 為:
?lang=en&mode=python&menu=%2Freeborg%2Fworlds%2Fmenus%2Fselect_collection_en.json&name=Alone&url=%2Freeborg%2Fworlds%2Ftutorial_en%2Falone.json
解析後的結果可能類似於:
url_query.queryKey = {
lang: "en",
mode: "python",
menu: "/reeborg/worlds/menus/select_collection_en.json",
name: "Alone",
url: "/reeborg/worlds/tutorial_en/alone.json"
};
相關函數
以下是部分相關的函數:
語言設置
function set_initial_language(url_query) {
var last_lang;
RUR.state.human_language = decodeURIComponent(url_query.queryKey.lang);
last_lang = localStorage.getItem("human_language");
if (probably_invalid(RUR.state.human_language)) {
if (!probably_invalid(last_lang)) {
RUR.state.human_language = last_lang;
} else {
RUR.state.human_language = RUR.initial_defaults.human_language;
}
}
document.getElementById('human-language').value = RUR.state.human_language;
$("#human-language").change(); // triggers the require UI changes
}
編程模式設置
function set_initial_input_method(url_query) {
var last_mode;
RUR.state.input_method = decodeURIComponent(url_query.queryKey.mode);
last_mode = localStorage.getItem("input_method");
if (probably_invalid(RUR.state.input_method)) {
if (!probably_invalid(last_mode)) {
RUR.state.input_method = last_mode;
} else {
RUR.state.input_method = RUR.initial_defaults.input_method;
}
}
document.getElementById("programming-mode").value = RUR.state.input_method;
$("#programming-mode").change(); // triggers the require UI changes
if (RUR.state.input_method === "blockly-py" || RUR.state.input_method === "blockly-js") {
restore_blockly();
}
}
世界菜單設置
function set_initial_menu(url_query) {
var last_menu;
var last_lang;
last_lang = localStorage.getItem("human_language");
if (last_lang !== RUR.state.human_language) {
RUR.state.current_menu = RUR.initial_defaults.initial_menu;
} else {
RUR.state.current_menu = decodeURIComponent(url_query.queryKey.menu);
last_menu = localStorage.getItem("world_menu");
if (probably_invalid(RUR.state.current_menu)) {
if (!probably_invalid(last_menu)) {
RUR.state.current_menu = last_menu;
} else {
RUR.state.current_menu = RUR.initial_defaults.initial_menu;
}
}
}
RUR.state.creating_menu = true;
RUR.load_world_file(RUR.state.current_menu);
if (RUR.file_io_status == "no link") {
RUR.make_default_menu(RUR.state.human_language);
}
RUR.state.creating_menu = false;
}
結論
- URL 中的每個參數(如
lang
、mode
、menu
、name
、url
)都由 RUR.permalink.parseUri
解析後存儲在 url_query.queryKey
中。
- 解析結果被用於設置應用的初始狀態,如語言、編程模式、菜單和世界。
- 未設定對應值的參數會使用默認值自動補全。
以下是 parseUri
函數和其相關上下文的詳細解析,來回答 URL 中的變數是如何被讀取和處理的:
parseUri
函數的作用
parseUri
是一個函數,用於解析 URL 並將其分解為多個部分,包括協議、主機、路徑、查詢參數等。這是 Reeborg 應用中處理 URL 的核心工具。
function parseUri (str) {
var o = parseUri.options,
m = o.parser[o.strictMode ? "strict" : "loose"].exec(str),
uri = {},
i = 14;
while (i--) uri[o.key[i]] = m[i] || "";
uri[o.q.name] = {};
uri[o.key[12]].replace(o.q.parser, function ($0, $1, $2) {
if ($1) uri[o.q.name][$1] = $2;
});
return uri;
}
解析過程:
-
定義解析選項: parseUri.options
包含解析 URL 的鍵、解析器及其他設置。
-
匹配 URL 結構: 使用正則表達式(o.parser
)將 URL 分解為多個部分,例如協議、主機、查詢參數等。
-
提取查詢參數: 查詢部分(URL 中的 ?
後部分)會進一步解析為鍵值對,並存儲在 uri.queryKey
中。
-
返回結果: 返回一個包含多個屬性的對象,這些屬性對應於 URL 的各個部分,例如:
{
protocol: "http",
host: "example.com",
path: "/some/path",
queryKey: {
lang: "en",
mode: "python",
menu: "/reeborg/worlds/menus/select_collection_en.json",
name: "Alone",
url: "/reeborg/worlds/tutorial_en/alone.json"
}
}
URL 變數的處理
在 Reeborg 的應用中,parseUri
的結果被用於設定應用的初始狀態,具體在 set_initial_state()
及相關函數中使用。
鍵值對映射:
lang
:設定語言(set_initial_language
裡處理)。
mode
:設定編程模式(set_initial_input_method
裡處理)。
menu
:設定世界菜單(set_initial_menu
裡處理)。
name
:設定世界名稱(RUR.state.world_name
)。
url
:設定世界的 URL(RUR.state.world_url
)。
URL 更新的功能
RUR.permalink.update_URI
用於在應用的狀態改變時更新瀏覽器的 URL:
RUR.permalink.update_URI = function() {
"use strict";
var url_query, permalink;
if (!RUR.state.session_initialized) {
return;
}
if (window.location.href.indexOf("#&togetherjs") != -1) {
return;
}
url_query = parseUri(window.location.href);
permalink = url_query.protocol + "://" + url_query.host;
if (url_query.port){
permalink += ":" + url_query.port;
}
permalink += url_query.path;
permalink += "?lang=" + encodeURIComponent(RUR.state.human_language) +
"&mode=" + encodeURIComponent(RUR.state.input_method) +
"&menu=" + encodeURIComponent(RUR.state.current_menu) +
"&name=" + encodeURIComponent(RUR.state.world_name) +
"&url=" + encodeURIComponent(RUR.state.world_url);
window.history.pushState("dummy", "dummy", permalink);
};
更新過程:
- 確保當前會話已初始化並且不在 TogetherJS 協作模式下。
- 生成新的 URL,依據當前的應用狀態(如語言、模式、菜單、世界名稱和 URL)。
- 使用
window.history.pushState
更新瀏覽器的 URL,而不刷新頁面。
總結
- 讀取 URL:
parseUri
函數解析 URL,並將查詢參數存儲為鍵值對。
- 設置應用狀態:這些參數被用於初始化語言、編程模式、菜單和世界。
- 更新 URL:
RUR.permalink.update_URI
根據應用狀態生成新的 URL,並更新瀏覽器地址欄。
Packages <<
Previous Next >> Parameters