wcm2025 網際內容管理 Scrum-1 demo 網站

  • Home
    • SMap
    • reveal
    • blog
  • About
    • list
    • Fossil
  • Tasks
    • task1
    • task2
    • task2.5
      • IPv6
    • task3
      • mind-map
    • task4
  • Reeborg
    • Challenge
    • Tutorial
    • Examples
    • rb
      • Program
    • Packages
    • URL
      • Parameters
  • Homework
    • HW1
      • Steps
      • Commands
    • HW2
  • Midterm
  • Final
  • Brython
Packages << Previous Next >> Parameters

URL

URL 參數解析過程

  1. 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"
};

  • 設置初始狀態: set_initial_state() 函數使用這些解析結果來設置應用的初始狀態:

    • set_initial_language(url_query):設置語言,例如 en。
    • set_initial_input_method(url_query):設置編程模式,例如 python。
    • set_initial_menu(url_query):設置菜單,例如 /reeborg/worlds/menus/select_collection_en.json。
    • RUR.state.world_url 和 RUR.state.world_name:
      • url_query.queryKey.url:設置世界的 URL(例如 /reeborg/worlds/tutorial_en/alone.json)。
      • url_query.queryKey.name:設置世界的名稱(例如 Alone)。
  • 處理內定值: 如果 lang、mode、menu、url 或 name 並未指定,程式會使用預設值(例如通過 RUR.initial_defaults)來填補。

相關函數

以下是部分相關的函數:

語言設置

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;
}

結論

  1. URL 中的每個參數(如 lang、mode、menu、name、url)都由 RUR.permalink.parseUri 解析後存儲在 url_query.queryKey 中。
  2. 解析結果被用於設置應用的初始狀態,如語言、編程模式、菜單和世界。
  3. 未設定對應值的參數會使用默認值自動補全。

以下是 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;
}

解析過程:

  1. 定義解析選項: parseUri.options 包含解析 URL 的鍵、解析器及其他設置。

  2. 匹配 URL 結構: 使用正則表達式(o.parser)將 URL 分解為多個部分,例如協議、主機、查詢參數等。

  3. 提取查詢參數: 查詢部分(URL 中的 ? 後部分)會進一步解析為鍵值對,並存儲在 uri.queryKey 中。

  4. 返回結果: 返回一個包含多個屬性的對象,這些屬性對應於 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);
};

更新過程:

  1. 確保當前會話已初始化並且不在 TogetherJS 協作模式下。
  2. 生成新的 URL,依據當前的應用狀態(如語言、模式、菜單、世界名稱和 URL)。
  3. 使用 window.history.pushState 更新瀏覽器的 URL,而不刷新頁面。

總結

  1. 讀取 URL:parseUri 函數解析 URL,並將查詢參數存儲為鍵值對。
  2. 設置應用狀態:這些參數被用於初始化語言、編程模式、菜單和世界。
  3. 更新 URL:RUR.permalink.update_URI 根據應用狀態生成新的 URL,並更新瀏覽器地址欄。

Packages << Previous Next >> Parameters

Copyright © All rights reserved | This template is made with by Colorlib