aboutsummaryrefslogtreecommitdiffstats
path: root/components/script/dom/urlhelper.rs
blob: d9e26e84263b21b6a06e31fa16f1fd383b5e098b (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

use dom::bindings::str::USVString;
use std::borrow::ToOwned;
use std::fmt::Write;
use url::urlutils::{UrlUtils, UrlUtilsWrapper};
use url::{SchemeData, Url, UrlParser};

#[derive(HeapSizeOf)]
pub struct UrlHelper;

impl UrlHelper {
    pub fn Hash(url: &Url) -> USVString {
        USVString(match url.fragment {
            None => "".to_owned(),
            Some(ref hash) if hash.is_empty() => "".to_owned(),
            Some(ref hash) => format!("#{}", hash)
        })
    }

    pub fn SetHash(url: &mut Url, value: USVString) {
        let mut wrapper = UrlUtilsWrapper { url: url, parser: &UrlParser::new() };
        let _ = wrapper.set_fragment(&value.0);
    }

    pub fn Host(url: &Url) -> USVString {
        USVString(match url.scheme_data {
            SchemeData::NonRelative(..) => "".to_owned(),
            SchemeData::Relative(ref scheme_data) => {
                let mut host = scheme_data.host.serialize();
                if let Some(port) = scheme_data.port {
                    write!(host, ":{}", port).unwrap();
                }
                host
            },
        })
    }

    pub fn SetHost(url: &mut Url, value: USVString) {
        let mut wrapper = UrlUtilsWrapper { url: url, parser: &UrlParser::new() };
        let _ = wrapper.set_host(&value.0);
    }

    pub fn Hostname(url: &Url) -> USVString {
        USVString(url.serialize_host().unwrap_or_else(|| "".to_owned()))
    }

    pub fn SetHostname(url: &mut Url, value: USVString) {
        let mut wrapper = UrlUtilsWrapper { url: url, parser: &UrlParser::new() };
        let _ = wrapper.set_host_and_port(&value.0);
    }

    pub fn Href(url: &Url) -> USVString {
        USVString(url.serialize())
    }

    pub fn Password(url: &Url) -> USVString {
        USVString(url.password().unwrap_or("").to_owned())
    }

    pub fn SetPassword(url: &mut Url, value: USVString) {
        let mut wrapper = UrlUtilsWrapper { url: url, parser: &UrlParser::new() };
        let _ = wrapper.set_password(&value.0);
    }

    pub fn Pathname(url: &Url) -> USVString {
        USVString(match url.scheme_data {
            SchemeData::NonRelative(ref scheme_data) => scheme_data.clone(),
            SchemeData::Relative(..) => url.serialize_path().unwrap()
        })
    }

    pub fn SetPathname(url: &mut Url, value: USVString) {
        let mut wrapper = UrlUtilsWrapper { url: url, parser: &UrlParser::new() };
        let _ = wrapper.set_path(&value.0);
    }

    pub fn Port(url: &Url) -> USVString {
        USVString(match url.port() {
            None => "".to_owned(),
            Some(port) => port.to_string(),
        })
    }

    pub fn SetPort(url: &mut Url, value: USVString) {
        let mut wrapper = UrlUtilsWrapper { url: url, parser: &UrlParser::new() };
        let _ = wrapper.set_port(&value.0);
    }

    pub fn Protocol(url: &Url) -> USVString {
        USVString(format!("{}:", url.scheme.clone()))
    }

    pub fn SetProtocol(url: &mut Url, value: USVString) {
        let mut wrapper = UrlUtilsWrapper { url: url, parser: &UrlParser::new() };
        let _ = wrapper.set_scheme(&value.0);
    }

    // https://html.spec.whatwg.org/multipage/#same-origin
    pub fn SameOrigin(urlA: &Url, urlB: &Url) -> bool {
        if urlA.host() != urlB.host() {
            return false
        }
        if urlA.scheme != urlB.scheme {
            return false
        }
        if urlA.port() != urlB.port() {
            return false
        }
        true
    }

    pub fn Search(url: &Url) -> USVString {
        USVString(match url.query {
            None => "".to_owned(),
            Some(ref query) if query.is_empty() => "".to_owned(),
            Some(ref query) => format!("?{}", query)
        })
    }

    pub fn SetSearch(url: &mut Url, value: USVString) {
        let mut wrapper = UrlUtilsWrapper { url: url, parser: &UrlParser::new() };
        let _ = wrapper.set_query(&value.0);
    }

    pub fn Username(url: &Url) -> USVString {
        USVString(url.username().unwrap_or("").to_owned())
    }

    pub fn SetUsername(url: &mut Url, value: USVString) {
        let mut wrapper = UrlUtilsWrapper { url: url, parser: &UrlParser::new() };
        let _ = wrapper.set_username(&value.0);
    }
}