summaryrefslogtreecommitdiffstats
path: root/chromium/third_party/WebKit/Source/devtools/front_end/common/ParsedURL.js
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/third_party/WebKit/Source/devtools/front_end/common/ParsedURL.js')
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/common/ParsedURL.js281
1 files changed, 281 insertions, 0 deletions
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/common/ParsedURL.js b/chromium/third_party/WebKit/Source/devtools/front_end/common/ParsedURL.js
new file mode 100644
index 00000000000..6f5d66f245f
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/common/ParsedURL.js
@@ -0,0 +1,281 @@
+/*
+ * Copyright (C) 2012 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GOOGLE INC. AND ITS CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GOOGLE INC.
+ * OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @constructor
+ * @param {string} url
+ */
+WebInspector.ParsedURL = function(url)
+{
+ this.isValid = false;
+ this.url = url;
+ this.scheme = "";
+ this.host = "";
+ this.port = "";
+ this.path = "";
+ this.queryParams = "";
+ this.fragment = "";
+ this.folderPathComponents = "";
+ this.lastPathComponent = "";
+
+ // RegExp groups:
+ // 1 - scheme (using the RFC3986 grammar)
+ // 2 - hostname
+ // 3 - ?port
+ // 4 - ?path
+ // 5 - ?fragment
+ var match = url.match(/^([A-Za-z][A-Za-z0-9+.-]*):\/\/([^\/:]*)(?::([\d]+))?(?:(\/[^#]*)(?:#(.*))?)?$/i);
+ if (match) {
+ this.isValid = true;
+ this.scheme = match[1].toLowerCase();
+ this.host = match[2];
+ this.port = match[3];
+ this.path = match[4] || "/";
+ this.fragment = match[5];
+ } else {
+ if (this.url.startsWith("data:")) {
+ this.scheme = "data";
+ return;
+ }
+ if (this.url === "about:blank") {
+ this.scheme = "about";
+ return;
+ }
+ this.path = this.url;
+ }
+
+ // First cut the query params.
+ var path = this.path;
+ var indexOfQuery = path.indexOf("?");
+ if (indexOfQuery !== -1) {
+ this.queryParams = path.substring(indexOfQuery + 1)
+ path = path.substring(0, indexOfQuery);
+ }
+
+ // Then take last path component.
+ var lastSlashIndex = path.lastIndexOf("/");
+ if (lastSlashIndex !== -1) {
+ this.folderPathComponents = path.substring(0, lastSlashIndex);
+ this.lastPathComponent = path.substring(lastSlashIndex + 1);
+ } else
+ this.lastPathComponent = path;
+}
+
+/**
+ * @param {string} url
+ * @return {!Array.<string>}
+ */
+WebInspector.ParsedURL.splitURL = function(url)
+{
+ var parsedURL = new WebInspector.ParsedURL(url);
+ var origin;
+ var folderPath;
+ var name;
+ if (parsedURL.isValid) {
+ origin = parsedURL.scheme + "://" + parsedURL.host;
+ if (parsedURL.port)
+ origin += ":" + parsedURL.port;
+ folderPath = parsedURL.folderPathComponents;
+ name = parsedURL.lastPathComponent;
+ if (parsedURL.queryParams)
+ name += "?" + parsedURL.queryParams;
+ } else {
+ origin = "";
+ folderPath = "";
+ name = url;
+ }
+ var result = [origin];
+ var splittedPath = folderPath.split("/");
+ for (var i = 1; i < splittedPath.length; ++i) {
+ if (!splittedPath[i])
+ continue;
+ result.push(splittedPath[i]);
+ }
+ result.push(name);
+ return result;
+}
+
+
+/**
+ * http://tools.ietf.org/html/rfc3986#section-5.2.4
+ * @param {string} path
+ * @return {string}
+ */
+
+WebInspector.ParsedURL.normalizePath = function(path)
+{
+ if (path.indexOf("..") === -1 && path.indexOf('.') === -1)
+ return path;
+
+ var normalizedSegments = [];
+ var segments = path.split("/");
+ for (var i = 0; i < segments.length; i++) {
+ var segment = segments[i];
+ if (segment === ".")
+ continue;
+ else if (segment === "..")
+ normalizedSegments.pop();
+ else if (segment)
+ normalizedSegments.push(segment);
+ }
+ var normalizedPath = normalizedSegments.join("/");
+ if (normalizedPath[normalizedPath.length - 1] === "/")
+ return normalizedPath;
+ if (path[0] === "/" && normalizedPath)
+ normalizedPath = "/" + normalizedPath;
+ if ((path[path.length - 1] === "/") || (segments[segments.length - 1] === ".") || (segments[segments.length - 1] === ".."))
+ normalizedPath = normalizedPath + "/";
+
+ return normalizedPath;
+}
+
+/**
+ * @param {string} baseURL
+ * @param {string} href
+ * @return {?string}
+ */
+WebInspector.ParsedURL.completeURL = function(baseURL, href)
+{
+ if (href) {
+ // Return special URLs as-is.
+ var trimmedHref = href.trim();
+ if (trimmedHref.startsWith("data:") || trimmedHref.startsWith("blob:") || trimmedHref.startsWith("javascript:"))
+ return href;
+
+ // Return absolute URLs as-is.
+ var parsedHref = trimmedHref.asParsedURL();
+ if (parsedHref && parsedHref.scheme)
+ return trimmedHref;
+ } else {
+ return baseURL;
+ }
+
+ var parsedURL = baseURL.asParsedURL();
+ if (parsedURL) {
+ if (parsedURL.isDataURL())
+ return href;
+ var path = href;
+
+ var query = path.indexOf("?");
+ var postfix = "";
+ if (query !== -1) {
+ postfix = path.substring(query);
+ path = path.substring(0, query);
+ } else {
+ var fragment = path.indexOf("#");
+ if (fragment !== -1) {
+ postfix = path.substring(fragment);
+ path = path.substring(0, fragment);
+ }
+ }
+
+ if (!path) { // empty path, must be postfix
+ var basePath = parsedURL.path;
+ if (postfix.charAt(0) === "?") {
+ // A href of "?foo=bar" implies "basePath?foo=bar".
+ // With "basePath?a=b" and "?foo=bar" we should get "basePath?foo=bar".
+ var baseQuery = parsedURL.path.indexOf("?");
+ if (baseQuery !== -1)
+ basePath = basePath.substring(0, baseQuery);
+ } // else it must be a fragment
+ return parsedURL.scheme + "://" + parsedURL.host + (parsedURL.port ? (":" + parsedURL.port) : "") + basePath + postfix;
+ } else if (path.charAt(0) !== "/") { // relative path
+ var prefix = parsedURL.path;
+ var prefixQuery = prefix.indexOf("?");
+ if (prefixQuery !== -1)
+ prefix = prefix.substring(0, prefixQuery);
+ prefix = prefix.substring(0, prefix.lastIndexOf("/")) + "/";
+ path = prefix + path;
+ } else if (path.length > 1 && path.charAt(1) === "/") {
+ // href starts with "//" which is a full URL with the protocol dropped (use the baseURL protocol).
+ return parsedURL.scheme + ":" + path + postfix;
+ } // else absolute path
+ return parsedURL.scheme + "://" + parsedURL.host + (parsedURL.port ? (":" + parsedURL.port) : "") + WebInspector.ParsedURL.normalizePath(path) + postfix;
+ }
+ return null;
+}
+
+WebInspector.ParsedURL.prototype = {
+ get displayName()
+ {
+ if (this._displayName)
+ return this._displayName;
+
+ if (this.isDataURL())
+ return this.dataURLDisplayName();
+ if (this.isAboutBlank())
+ return this.url;
+
+ this._displayName = this.lastPathComponent;
+ if (!this._displayName)
+ this._displayName = (this.host || "") + "/";
+ if (this._displayName === "/")
+ this._displayName = this.url;
+ return this._displayName;
+ },
+
+ /**
+ * @return {string}
+ */
+ dataURLDisplayName: function()
+ {
+ if (this._dataURLDisplayName)
+ return this._dataURLDisplayName;
+ if (!this.isDataURL())
+ return "";
+ this._dataURLDisplayName = this.url.trimEnd(20);
+ return this._dataURLDisplayName;
+ },
+
+ /**
+ * @return {boolean}
+ */
+ isAboutBlank: function()
+ {
+ return this.url === "about:blank";
+ },
+
+ /**
+ * @return {boolean}
+ */
+ isDataURL: function()
+ {
+ return this.scheme === "data";
+ }
+}
+
+/**
+ * @return {?WebInspector.ParsedURL}
+ */
+String.prototype.asParsedURL = function()
+{
+ var parsedURL = new WebInspector.ParsedURL(this.toString());
+ if (parsedURL.isValid)
+ return parsedURL;
+ return null;
+}