Skip to content
This repository has been archived by the owner on Sep 6, 2021. It is now read-only.

Replace percent-encoded characters in URL Code Hint List with regular characters #5677

Closed
wants to merge 10 commits into from
56 changes: 49 additions & 7 deletions src/extensions/default/UrlCodeHints/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -139,9 +139,10 @@ define(function (require, exports, module) {
// convert to doc relative path
var entryStr = entry.fullPath.replace(docDir, "");

// code hints show the same strings that are inserted into text,
// so strings in list will be encoded. wysiwyg, baby!
unfiltered.push(encodeURI(entryStr));
// code hints show the unencoded string so the
// choices are easier to read. The encoded string
// will still be inserted into the editor.
unfiltered.push(entryStr);
}
});

Expand Down Expand Up @@ -225,7 +226,40 @@ define(function (require, exports, module) {
};

/**
* Determines whether font hints are available in the current editor
* Helper function that cleans partially or malformed encoded characters
* in a URI, then decodes it.
*
* @param {string} URI
* The current URI that needs to be cleaned and decoded
*
* @return {string}
* The clean, decoded URI. Partially typed encoded characters at the end
* of the URI are stripped off. Any encoded characters in the string that
* would make decodeURI() fail are interpreted as literal characters instead.
*/
UrlCodeHints.prototype._cleanAndDecodeURI = function (URI) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This might need a better function name. Couldn't think of a good one that encompassed exactly what this function does, which is that it makes sure that any partial, or complete, percent-encoded URIs an end user manually enters into the editor matches the hint list as best it can, without making decodeURI() throw an exception.

A percent sign could be literal ("100% cool.html"), or it could be part of a percent-encoded character ("%20" space character), or it could be a Unicode character encoding ("%C3%A7" ç character). Users will rarely be manually typing percent-encoded characters into the editor, so I used a fairly simple heuristic that performs adequately enough.

var matchResults,
finalURI = URI;

// If there is a partially encoded character on the end, strip it off
matchResults = finalURI.match(/%[\dA-Fa-f]?$/); // e.g. "%", "%5", "%A", "%d"
if (matchResults) {
finalURI = finalURI.substring(0, matchResults.index);
}

// Decode any encoded characters, checking for incorrect formatting
try {
finalURI = decodeURI(finalURI);
} catch (err) {
// do nothing, finalURI does not change...
// treat all characters as literal characters
}

return finalURI;
};

/**
* Determines whether url hints are available in the current editor
* context.
*
* @param {Editor} editor
Expand Down Expand Up @@ -339,6 +373,8 @@ define(function (require, exports, module) {
query = "";
}

query = this._cleanAndDecodeURI(query);

var hintsAndSortFunc = this._getUrlHints({queryStr: query});
var hints = hintsAndSortFunc.hints;
if (hints instanceof Array) {
Expand All @@ -356,12 +392,12 @@ define(function (require, exports, module) {
}
}
}

return (query !== null);
};

/**
* Returns a list of availble font hints, if possible, for the current
* Returns a list of available url hints, if possible, for the current
* editor context.
*
* @return {jQuery.Deferred|{
Expand Down Expand Up @@ -449,7 +485,9 @@ define(function (require, exports, module) {
} else {
return null;
}


query.queryStr = this._cleanAndDecodeURI(query.queryStr);

if (query.queryStr !== null) {
filter = query.queryStr;
var hintsAndSortFunc = this._getUrlHints(query);
Expand Down Expand Up @@ -504,6 +542,10 @@ define(function (require, exports, module) {
*/
UrlCodeHints.prototype.insertHint = function (completion) {
var mode = this.editor.getModeForSelection();

// Encode the string just prior to inserting the hint into the editor
completion = encodeURI(completion);

if (mode === "html") {
return this.insertHtmlHint(completion);
} else if (mode === "css") {
Expand Down