NOTICE: By continued use of this site you understand and agree to the binding Terms of Service and Privacy Policy.
// ==UserScript== // @name URLs Need Titles // @namespace UNT // @description When you paste a URL to a friend, it is useful if it contains the title of the page. This script adds these missing titles for common websites using # part of URL. In other words, it turns non-semantic URLs into semantic URLs! // @version 1.3.0 // @include http://*/* // @include https://*/* // @grant none // ==/UserScript== // For example, this script will change this address: // // http://www.imdb.com/title/tt1155592/ // // into this address: // // http://www.imdb.com/title/tt1155592/#Man_on_Wire_(2008) // // which is far more useful to paste to other people. var overwriteExistingHash = true; var rules = [ /* An example rule: { changeTitle: true / false, Some of the rules do not change the URL, but change the page title instead. This can be useful for bookmarking. hostMatch: "youtube.TLD", All subdomains will be accepted, e.g. somewhere.youtube.com. TLD will match one or two toplevel domain elements, e.g. "youtube.ath.cx" or "youtube.net". pathMatch: "/watch", This regex will be wrapped with ^..$ so use .* at either end for wildcards. Note that path does not include the search part of the URL, "?q=squash&type=image". Filtering on this part of the URL may be added later. If left blank all paths will be accepted. getTitle: function(){...} A function which returns a sensible title for this page. If left blank will just grab document.title. } */ /* // Oh dear, this has started causing annoying reloads. TODO Perhaps we can do it with pushState instead... { hostMatch: "youtube.TLD", pathMatch: "/watch", getTitle: function(){ return document.title.replace(/ - YouTube$/,''); } }, */ { hostMatch: "xkcd.TLD", pathMatch: ".*[0-9]+/", getTitle: function(){ return document.title.replace(/^xkcd: /,''); } }, { hostMatch: "imdb.TLD", pathMatch: ".*title.*", getTitle: function(){ return document.title.replace(/ - IMDb/,''); } }, { hostMatch: "pouet.net", pathMatch: ".*", getTitle: function(){ return document.title.replace(/ :: pouët.net$/,''); } }, { hostMatch: "userscripts.org", pathMatch: "/scripts/show/.*", getTitle: function(){ return document.title.replace(" for Greasemonkey",''); } }, { hostMatch: "bbc.co.uk", pathMatch: "/news/.*", getTitle: function(){ return document.title.replace(/BBC News - /,''); } }, { hostMatch: "imgur.com", pathMatch: "/.+", getTitle: function(){ return document.title.replace(/ - Imgur/,''); } }, { hostMatch: "9gag.com", pathMatch: "/gag/.*", getTitle: function(){ return document.title.replace(/ - 9GAG$/,''); } }, { hostMatch: "codepen.io", pathMatch: "/..*", /* Not the front page */ getTitle: function(){ return document.title.replace(/ - CodePen$/,''); } }, { hostMatch: "unrealadmin.org", getTitle: function(){ return document.title.replace(/ - The Unreal Admins Page .*/,''); } }, { hostMatch: "vim.org", getTitle: function(){ // When viewing user profile page if (document.location.pathname.indexOf("/profile.php") >= 0) { var username = document.evaluate("//td[string(.)='user name']/following-sibling::*",document,null,6,null).snapshotItem(0).textContent; // maybe I should start using jquery return username+"'s profile"; } // Otherwise (good when viewing a script page) return document.title.replace(/ - .*/,''); } }, // Mid 2016: They are actually doing this now, so this script is no longer needed. //{ // changeTitle: true, // hostMatch: "github.com", // pathMatch: "/[^/]*/[^/]*/*", // getTitle: function(){ // //var repoDescriptionElems = document.getElementsByClassName("repository-description"); // // Late 2015 // var repoDescriptionElems = document.getElementsByClassName("repository-meta-content"); // if (repoDescriptionElems) { // var repoDescription = repoDescriptionElems[0].textContent.trim(); // // For a while their titles were "<author_name>/<repo_name> <weird-dot> GitHub" but right now they just have the repo path. // document.title = document.title.replace(/(\s+[^ ]*\s+GitHub|)$/, '') + " - "+repoDescription; // } // return null; // } //}, { changeTitle: true, hostMatch: "engineers.sg", pathMatch: "/video/.*", getTitle: function(){ var titleElement = document.querySelector('h4'); if (titleElement && titleElement.textContent) { document.title = titleElement.textContent + " - Engineers.SG"; } return null; } } ]; function check() { if (document.location.hash && !overwriteExistingHash) { return; } rules.forEach(checkRule); } function checkRule(rule) { var hostRegexp = '(^|\\.)' + rule.hostMatch.replace(/\.TLD$/, "(\\.[^.]*$|\\.[^.]*\\.[^.]*$)") + '$'; if (document.location.host.match(hostRegexp)) { if (rule.pathMatch) { var pathRegexp = '^' + rule.pathMatch + '$'; if (!document.location.pathname.match(pathRegexp)) { return false; } } var newTitle = ( rule.getTitle ? rule.getTitle() : document.title ); if (newTitle == '' || newTitle == null) { console.log("Failed to get new title for "+document.location+" from "+document.title); } setTitle(newTitle); } } function setTitle(title) { if (title) { // "_"s paste better into IRC, since " "s become "%20"s which are hard to read. The second and third parts trim "_"s and newlines from the start and end of the string. title = title.replace(/ /g,'_').replace(/^[\r\n_]*/,'').replace(/[\r\n_]*$/,''); var strippedHref = document.location.href.replace(/#.*/,''); document.location.replace(strippedHref + '#' + title); // Does not alter browser history // document.location.hash = title; // Crashes Chrome less often } } // 2010/11: Waiting a bit can prevent crashing (e.g. YouTube in Chrome). setTimeout(check,5000); // vim: ts=4 sw=4 expandtab