Merge pull request #100 from johnbeard/parentroot

Add URL parent and root functions (gu and gU)
This commit is contained in:
Oliver Blanthorn 2017-11-21 17:28:33 +00:00 committed by GitHub
commit ffaaaf55d7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 149 additions and 4 deletions

View file

@ -62,7 +62,7 @@ import * as keydown from "./keydown_background"
//#background_helper
import {activeTab, activeTabId} from './lib/webext'
//#content_helper
import {incrementUrl} from "./url_util"
import {incrementUrl, getUrlRoot, getUrlParent} from "./url_util"
/** @hidden */
//#background_helper
@ -283,6 +283,28 @@ export function urlincrement(count = 1){
}
}
/** Go to the root domain of the current URL
*/
//#content
export function urlroot (){
let rootUrl = getUrlRoot(window.location)
if (rootUrl !== null) {
window.location.href = rootUrl.href
}
}
/** Go to the parent URL of the current tab's URL
*/
//#content
export function urlparent (){
let parentUrl = getUrlParent(window.location)
if (parentUrl !== null) {
window.location.href = parentUrl.href
}
}
//#background
export function zoom(level=0){
level = level > 3 ? level / 100 : level

View file

@ -39,6 +39,8 @@ export const DEFAULTNMAPS = {
"gt": "tabnext",
"gT": "tabprev",
"gr": "reader",
"gu": "urlparent",
"gU": "urlroot",
":": "fillcmdline",
"s": "fillcmdline open google",
"S": "fillcmdline tabopen google",

View file

@ -1,6 +1,6 @@
/** Some tests for URL utilities */
import {incrementUrl} from './url_util'
import {incrementUrl, getUrlRoot, getUrlParent} from './url_util'
function test_increment() {
@ -27,4 +27,56 @@ function test_increment() {
}
}
function test_root() {
let cases = [
// simple URL
["http://example.com/dir/page.html", "http://example.com/"],
// already root, with subdir
["http://www.example.com/", "http://www.example.com/"],
// unsupported protocol
["about:config", null],
]
for (let [url, exp_root] of cases) {
let root = getUrlRoot(new URL(url))
test(`root of ${url} --> ${exp_root}`,
() => expect(root ? root.href : root).toEqual(exp_root)
)
}
}
function test_parent() {
let cases = [
// root URL, nothing to do!
["http://example.com", null],
// URL with query string
["http://example.com?key=value", "http://example.com/"],
// url with hash/anchor - strip the fragment
["http://example.com#anchor", "http://example.com/"],
// query + hash: lose the hash only
["http://example.com?key=val#hash", "http://example.com/?key=val"],
// single level path
["http://example.com/path", "http://example.com/"],
// multi-level path
["http://example.com/path1/path2", "http://example.com/path1"],
// subdomains
["http://sub.example.com", "http://example.com/"],
// subdom with path, leave subdom
["http://sub.example.com/path", "http://sub.example.com/"],
]
for (let [url, exp_parent] of cases) {
let parent = getUrlParent(new URL(url))
test (`parent of ${url} --> ${exp_parent}`,
() => expect(parent ? parent.href : parent).toEqual(exp_parent)
)
}
}
test_increment()
test_root()
test_parent()

View file

@ -3,7 +3,7 @@
/** Increment the last number in a URL.
*
* (perhaps this could be made so you can select the "nth" number in a
* (perhaps this could be made so you can select the "nth" number in a
* URL rather than just the last one?)
*
* @param url the URL to increment
@ -25,7 +25,7 @@ export function incrementUrl(url, count) {
// Re-pad numbers that were zero-padded to be the same length:
// 0009 + 1 => 0010
if (number.match(/^0/)) {
if (number.match(/^0/)) {
while (newNumberStr.length < number.length) {
newNumberStr = "0" + newNumberStr;
}
@ -33,3 +33,72 @@ export function incrementUrl(url, count) {
return pre + newNumberStr + post
}
/** Get the root of a URL
*
* @param url the url to find the root of
* @return the root of the URL, or the original URL when the URL isn't
* suitable for finding the root of.
*/
export function getUrlRoot(url) {
// exclude these special protocols for now;
if (/(about|mailto):/.test(url.protocol)) {
return null
}
// this works even for file:/// where the root is ""
return new URL(url.protocol + "//" + (url.host || ""))
}
/** Get the parent of the current URL. Parent is determined as:
*
* * if there is a hash fragment, strip that, or
* * If there is a query string, strip that, or
* * Remove one level from the path if there is one, or
* * Remove one subdomain from the front if there is one
*
* @param url the URL to get the parent of
* @return the parent of the URL, or null if there is no parent
*/
export function getUrlParent(url) {
// exclude these special protocols where parents don't really make sense
if (/(about|mailto):/.test(url.protocol)) {
return null
}
let parent = new URL(url)
// strip, in turn, hash/fragment and query/search
if (parent.hash) {
parent.hash = ''
return parent
}
if (parent.search) {
parent.search = ''
return parent
}
// pathname always starts '/'
if (parent.pathname !== '/') {
let path = parent.pathname.substring(1).split('/')
path.pop()
parent.pathname = path.join('/')
return parent
}
// strip off the first subdomain if there is one
{
let domains = parent.host.split('.')
// more than domain + TLD
if (domains.length > 2) {
//domains.pop()
parent.host = domains.slice(1).join('.')
return parent
}
}
// nothing to trim off URL, so no parent
return null
}