1
0
mirror of https://github.com/Jermolene/TiddlyWiki5 synced 2024-12-02 06:19:57 +00:00

Fix to match standards

This commit is contained in:
Scott Sauyet 2023-10-21 18:01:55 -04:00
parent 0cabd09871
commit c7ff7ab65b
3 changed files with 99 additions and 103 deletions

View File

@ -287,135 +287,115 @@ $tw.utils.decodeURIComponentSafe = function(s) {
return v; return v;
}; };
/************* $tw.utils.map = function(fn) {
Code to make the permalink/permaview URLs more readable. return function (xs) {
(These comments are just to help reviewers; they will eventually be removed.) var results = [];
***************/ for (var i = 0; i < xs.length; i++) {
results.push (fn(xs[i]));
}
return results;
}
}
$tw.utils.filter = function(fn) {
return function (xs) {
const results = []
for (var i = 0; i < xs.length; i++) {
if (fn(xs[i])) {
results.push(xs[i])
}
}
return results;
}
}
/************* // The character that will substitute for a space in the URL
Helpers for encoding/decoding URIs. **Note** that these are throw-away, only var SPACE_SUBSTITUTE = "_";
used to temporarily build `charMatch`, `spaceMatch`, `sentenceEnding`, and
`sentenceTrailing`, all of which will eventually be hard-coded.
***************/
/* // The character added to the end to avoid ending with `.`, `?`, `!` or the like
The character that will substitute for a space in the URL var TRAILER = "_";
*/
var SPACE = "_";
/* // The character that will separate out the list elements in the URL
The character added to the end to avoid ending with `.`, `?`, `!` or the like
*/
var TRAILER = '_';
/*
The character that will separate out the list elements in the URL
*/
var CONJUNCTION = ";"; var CONJUNCTION = ";";
/* // Those of the allowed url characters claimed by TW
Those of the allowed url characters claimed by TW var CLAIMED = [SPACE_SUBSTITUTE, ":", CONJUNCTION];
*/
var CLAIMED = [SPACE, ":", CONJUNCTION];
/* // Non-alphanumeric characters allowed in a URL fragment
Non-alphanumeric characters allowed in a URL fragment // More information at https://www.rfc-editor.org/rfc/rfc3986#appendix-A
More information at https://www.rfc-editor.org/rfc/rfc3986#appendix-A
*/
var VALID_IN_URL_FRAGMENT = "-._~!$&'()*+,;=:@/?"; var VALID_IN_URL_FRAGMENT = "-._~!$&'()*+,;=:@/?";
/* // The subset of the pchars we will not percent-encode in permalinks/permaviews
The subset of the pchars we will not percent-encode in permalinks/permaviews var SUBSTITUTES = VALID_IN_URL_FRAGMENT.split("").filter(function(c){return CLAIMED.indexOf(c) === -1});
*/
var substitutes = VALID_IN_URL_FRAGMENT.split('').filter(function(c){return CLAIMED.indexOf(c) === -1});
// A regex to match the percent-encoded characters we will want to replace.
/************* // Something similar to the following, depending on SPACE and CONJUNCTION
The more permanent implementation. These helpers (`charMatch`, `spaceMatch`, // /(%2D|%2E|%7E|%21|%24|%26|%27|%28|%29|%2A|%2B|%3B|%3D|%40|%2F|%3F)/g
`sentenceEnding`, `sentenceTrailing`) will be hard-coded, not derived. var CHAR_MATCH = new RegExp(
***************/ "(" + SUBSTITUTES.map(function(c) {
/*
A regex to match the percent-encoded characters we will want to replace.
Something similar to the following, depending on SPACE and CONJUNCTION
/(%2D|%2E|%7E|%21|%24|%26|%27|%28|%29|%2A|%2B|%3B|%3D|%40|%2F|%3F)/g
*/
var charMatch = new RegExp(
"(" + substitutes.map(function(c) {
return "%" + c.charCodeAt(0).toString(16).toUpperCase() return "%" + c.charCodeAt(0).toString(16).toUpperCase()
}).join('|') + ')', }).join("|") + ")",
"g" "g"
); );
/* // A regex to match the SPACE_SUBSTITUTE character
A regex to match the SPACE character var SPACE_MATCH = new RegExp("(\\" + SPACE_SUBSTITUTE + ")", "g");
*/
var spaceMatch = new RegExp("(\\" + SPACE + ")", "g");
/* // A regex to match URLs ending with sentence-ending punctuation
A regex to match URLs ending with sentence-ending punctuation var SENTENCE_ENDING = new RegExp("(\\.|\\!|\\?|\\" + TRAILER + ")$", "g");
*/
var sentenceEnding = new RegExp("(\\.|\\!|\\?|\\" + TRAILER + ")$", "g");
/* // A regex to match URLs ending with sentence-ending punctuation plus the TRAILER
A regex to match URLs ending with sentence-ending punctuation plus the TRAILER var SENTENCE_TRAILING = new RegExp("(\\.|\\!|\\?|\\" + TRAILER + ")\\" + TRAILER + "$", "g");
*/
var sentenceTrailing = new RegExp("(\\.|\\!|\\?|\\" + TRAILER + ")\\" + TRAILER + "$", "g");
/* // An object mapping the percent encodings back to their source characters
An object mapping the percent encodings back to their source characters var PCT_CHAR_MAP = SUBSTITUTES.reduce(function (a, c) {
*/ a["%" + c.charCodeAt(0).toString(16).toUpperCase()] = c
var pctCharMap = substitutes.reduce(function (a, c) {
a['%' + c.charCodeAt(0).toString(16).toUpperCase()] = c
return a return a
}, {}); }, {});
/* // Convert a URI List Component encoded string (with the `SPACE_SUBSTITUTE`
Convert a URI List Component encoded string (with the `SPACE` value // value as an allowed replacement for the space character) to a string
as an allowed replacement for the space character) to a string
*/
$tw.utils.decodeTWURIList = function(s) { $tw.utils.decodeTWURIList = function(s) {
return $tw.utils.decodeURIComponentSafe( var parts = s.replace(SENTENCE_TRAILING, "$1").split(CONJUNCTION);
s.replace(sentenceTrailing, "$1") var withSpaces = $tw.utils.map(function(s) {return s.replace(SPACE_MATCH, " ")})(parts);
.split(CONJUNCTION) var withBrackets = $tw.utils.map(function(s) {return s.indexOf(" ") >= 0 ? "[[" + s + "]]" : s})(withSpaces);
.map(function(s) {return s.replace(spaceMatch, " ")}) return $tw.utils.decodeURIComponentSafe(withBrackets.join(" "));
.map(function(s) {return s.indexOf(" ") >= 0 ? "[[" + s + "]]" : s})
.join(" ")
)
}; };
/* // Convert a URI Target Component encoded string (with the `SPACE_SUBSTITUTE`
Convert a URI Target Component encoded string (with the `SPACE` value // value as an allowed replacement for the space character) to a string
as an allowed replacement for the space character) to a string
*/
$tw.utils.decodeTWURITarget = function(s) { $tw.utils.decodeTWURITarget = function(s) {
return $tw.utils.decodeURIComponentSafe( return $tw.utils.decodeURIComponentSafe(
s.replace(sentenceTrailing, "$1").replace(spaceMatch, " ") s.replace(SENTENCE_TRAILING, "$1").replace(SPACE_MATCH, " ")
) )
}; };
/* // Convert a URIComponent encoded title string (with the `SPACE_SUBSTITUTE`
Convert a URIComponent encoded string (with the `SPACE` value // value as an allowed replacement for the space character) to a string
as an allowed replacement for the space character) to a string $tw.utils.encodeTiddlerTitle = function(s) {
*/ var extended = s.replace(SENTENCE_ENDING, "$1" + TRAILER)
$tw.utils.encodeTWURIComponent = function(s) { var encoded = encodeURIComponent(extended);
return s.replace(sentenceEnding, "$1" + TRAILER) var substituted = encoded.replace(/\%20/g, SPACE_SUBSTITUTE);
.split(/\[\[|\]\]\s?/) return substituted.replace(CHAR_MATCH, function(_, c) {
.filter(Boolean) return PCT_CHAR_MAP[c];
.map(function(s) {return s.trim()}) });
.map(function(s) {return encodeURIComponent(s)})
.map(function(s) {return s.replace(/\%20/g, SPACE)})
.map(function(s) {return s.replace(charMatch, function(_, c) {
return pctCharMap[c]})
})
.join(CONJUNCTION)
}; };
/************* // Convert a URIComponent encoded filter string (with the `SPACE_SUBSTITUTE`
End of changes // value as an allowed replacement for the space character) to a string
***************/ $tw.utils.encodeFilterPath = function(s) {
var parts = s.replace(SENTENCE_ENDING, "$1" + TRAILER)
.replace(/\[\[(.+?)\]\]/g, function (_, t) {return t.replace(/ /g, SPACE_SUBSTITUTE )})
.split(" ");
var nonEmptyParts = $tw.utils.filter(Boolean)(parts);
var trimmed = $tw.utils.map(function(s) {return s.trim()})(nonEmptyParts);
var encoded = $tw.utils.map(function(s) {return encodeURIComponent(s)})(trimmed);
var substituted = $tw.utils.map(function(s) {return s.replace(/\%20/g, SPACE_SUBSTITUTE)})(encoded);
var replaced = $tw.utils.map(function(s) {return s.replace(CHAR_MATCH, function(_, c) {
return PCT_CHAR_MAP[c]});
})(substituted);
return replaced.join(CONJUNCTION);
};
/* /*
Convert a URI encoded string to a string safely Convert a URI encoded string to a string safely

View File

@ -198,19 +198,19 @@ function updateLocationHash(options) {
// Assemble the location hash // Assemble the location hash
switch(options.updateAddressBar) { switch(options.updateAddressBar) {
case "permalink": case "permalink":
$tw.locationHash = "#" + $tw.utils.encodeTWURIComponent(targetTiddler); $tw.locationHash = "#" + $tw.utils.encodeTiddlerTitle(targetTiddler);
break; break;
case "permaview": case "permaview":
$tw.locationHash = "#" + $tw.utils.encodeTWURIComponent(targetTiddler) + ":" + $tw.utils.encodeTWURIComponent($tw.utils.stringifyList(storyList)); $tw.locationHash = "#" + $tw.utils.encodeTiddlerTitle(targetTiddler) + ":" + $tw.utils.encodeFilterPath($tw.utils.stringifyList(storyList));
break; break;
} }
// Copy URL to the clipboard // Copy URL to the clipboard
switch(options.copyToClipboard) { switch(options.copyToClipboard) {
case "permalink": case "permalink":
$tw.utils.copyToClipboard($tw.utils.getLocationPath() + "#" + $tw.utils.encodeTWURIComponent(targetTiddler)); $tw.utils.copyToClipboard($tw.utils.getLocationPath() + "#" + $tw.utils.encodeTiddlerTitle(targetTiddler));
break; break;
case "permaview": case "permaview":
$tw.utils.copyToClipboard($tw.utils.getLocationPath() + "#" + $tw.utils.encodeTWURIComponent(targetTiddler) + ":" + $tw.utils.encodeTWURIComponent($tw.utils.stringifyList(storyList))); $tw.utils.copyToClipboard($tw.utils.getLocationPath() + "#" + $tw.utils.encodeTiddlerTitle(targetTiddler) + ":" + $tw.utils.encodeFilterPath($tw.utils.stringifyList(storyList)));
break; break;
} }
// Only change the location hash if we must, thus avoiding unnecessary onhashchange events // Only change the location hash if we must, thus avoiding unnecessary onhashchange events

View File

@ -40,6 +40,22 @@ There are technical restrictions on the legal characters in an URL fragment. To
Both the target tiddler title and the story filter should be URL encoded (but not the separating colon). TiddlyWiki generates properly encoded URLs which can look quite ugly. However, in practice browsers will usually perfectly happily process arbitrary characters in URL fragments. Thus when creating permalinks manually you can choose to ignore URL encoding. Both the target tiddler title and the story filter should be URL encoded (but not the separating colon). TiddlyWiki generates properly encoded URLs which can look quite ugly. However, in practice browsers will usually perfectly happily process arbitrary characters in URL fragments. Thus when creating permalinks manually you can choose to ignore URL encoding.
!! Simpler URLS
<<.from-version "5.2.3">> The URLs generated are simplified from the hard-to-read percent encoding when feasible. Spaces are replaced with underscores (`_`), many punctuation characters are allowed to remain unencoded, and permaview filters receive a simpler encoding. For example the tiddler "Hard Linebreaks with CSS - Example", which percent-encoded would look like
> @@font-family:monospace;#Hard%20Linebreaks%20with%20CSS%20-%20Example@@
instead looks like
> @@font-family:monospace;#Hard_Linebreaks_with_CSS_-_Example@@
Existing story filter URLs like
> @@font-family:monospace;#:[tag[Features]]%20+[limit[5]]@@
will continue to work.
! Permalink Behaviour ! Permalink Behaviour
Two important aspects of TiddlyWiki's behaviour with permalinks can be controlled via options in the [[control panel|$:/ControlPanel]] <<.icon $:/core/images/options-button>> ''Settings'' tab: Two important aspects of TiddlyWiki's behaviour with permalinks can be controlled via options in the [[control panel|$:/ControlPanel]] <<.icon $:/core/images/options-button>> ''Settings'' tab: