summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/SMAPI.Web/Views/JsonValidator/Index.cshtml4
-rw-r--r--src/SMAPI.Web/wwwroot/Content/css/json-validator.css4
-rw-r--r--src/SMAPI.Web/wwwroot/Content/js/json-validator.js123
3 files changed, 127 insertions, 4 deletions
diff --git a/src/SMAPI.Web/Views/JsonValidator/Index.cshtml b/src/SMAPI.Web/Views/JsonValidator/Index.cshtml
index cd7ca912..6658e7b9 100644
--- a/src/SMAPI.Web/Views/JsonValidator/Index.cshtml
+++ b/src/SMAPI.Web/Views/JsonValidator/Index.cshtml
@@ -107,7 +107,7 @@ else if (Model.PasteID != null)
@foreach (JsonValidatorErrorModel error in Model.Errors)
{
<tr>
- <td>@error.Line</td>
+ <td><a href="#L@(error.Line)">@error.Line</a></td>
<td>@error.Path</td>
<td>@error.Message</td>
</tr>
@@ -121,6 +121,6 @@ else if (Model.PasteID != null)
}
<h2>Raw content</h2>
- <pre class="sunlight-highlight-javascript">@Model.Content</pre>
+ <pre id="raw-content" class="sunlight-highlight-javascript">@Model.Content</pre>
</div>
}
diff --git a/src/SMAPI.Web/wwwroot/Content/css/json-validator.css b/src/SMAPI.Web/wwwroot/Content/css/json-validator.css
index f9aeb18b..d4a43032 100644
--- a/src/SMAPI.Web/wwwroot/Content/css/json-validator.css
+++ b/src/SMAPI.Web/wwwroot/Content/css/json-validator.css
@@ -72,6 +72,10 @@
background: #fff;
}
+#output div.sunlight-line-highlight-active {
+ background-color: #eeeacc;
+}
+
/*********
** Upload form
*********/
diff --git a/src/SMAPI.Web/wwwroot/Content/js/json-validator.js b/src/SMAPI.Web/wwwroot/Content/js/json-validator.js
index 3f7a1775..265e0c5e 100644
--- a/src/SMAPI.Web/wwwroot/Content/js/json-validator.js
+++ b/src/SMAPI.Web/wwwroot/Content/js/json-validator.js
@@ -1,20 +1,139 @@
/* globals $ */
var smapi = smapi || {};
+
+/**
+ * Manages the logic for line range selections.
+ * @param {int} maxLines The maximum number of lines in the content.
+ */
+smapi.LineNumberRange = function (maxLines) {
+ var self = this;
+
+ /**
+ * @var {int} minLine The first line in the selection, or null if no lines selected.
+ */
+ self.minLine = null;
+
+ /**
+ * @var {int} maxLine The last line in the selection, or null if no lines selected.
+ */
+ self.maxLine = null;
+
+ /**
+ * Parse line numbers from a URL hash.
+ * @param {string} hash the URL hash to parse.
+ */
+ self.parseFromUrlHash = function (hash) {
+ self.minLine = null;
+ self.maxLine = null;
+
+ // parse hash
+ var hashParts = hash.match(/^#L(\d+)(?:-L(\d+))?$/);
+ if (!hashParts || hashParts.length <= 1)
+ return;
+
+ // extract min/max lines
+ self.minLine = parseInt(hashParts[1]);
+ self.maxLine = parseInt(hashParts[2]) || self.minLine;
+ };
+
+ /**
+ * Generate a URL hash for the current line range.
+ * @returns {string} The generated URL hash.
+ */
+ self.buildHash = function() {
+ if (!self.minLine)
+ return "";
+ else if (self.minLine === self.maxLine)
+ return "#L" + self.minLine;
+ else
+ return "#L" + self.minLine + "-L" + self.maxLine;
+ }
+
+ /**
+ * Get a list of all selected lines.
+ * @returns {Array<int>} The selected line numbers.
+ */
+ self.getLinesSelected = function() {
+ // format
+ if (!self.minLine)
+ return [];
+
+ var lines = [];
+ for (var i = self.minLine; i <= self.maxLine; i++)
+ lines.push(i);
+ return lines;
+ };
+
+ return self;
+};
+
+/**
+ * UI logic for the JSON validator page.
+ * @param {any} sectionUrl The base JSON validator page URL.
+ * @param {any} pasteID The Pastebin paste ID for the content being viewed, if any.
+ */
smapi.jsonValidator = function (sectionUrl, pasteID) {
/**
+ * The original content element.
+ */
+ var originalContent = $("#raw-content").clone();
+
+ /**
+ * The currently highlighted lines.
+ */
+ var selection = new smapi.LineNumberRange();
+
+ /**
* Rebuild the syntax-highlighted element.
*/
var formatCode = function () {
- Sunlight.highlightAll();
+ // reset if needed
+ $(".sunlight-container").replaceWith(originalContent.clone());
+
+ // apply default highlighting
+ Sunlight.highlightAll({
+ lineHighlight: selection.getLinesSelected()
+ });
+
+ // fix line links
+ $(".sunlight-line-number-margin a").each(function() {
+ var link = $(this);
+ var lineNumber = parseInt(link.text());
+ link
+ .attr("id", "L" + lineNumber)
+ .attr("href", "#L" + lineNumber)
+ .removeAttr("name")
+ .data("line-number", lineNumber);
+ });
+ };
+
+ /**
+ * Scroll the page so the selected range is visible.
+ */
+ var scrollToRange = function() {
+ if (!selection.minLine)
+ return;
+
+ var targetLine = Math.max(1, selection.minLine - 5);
+ $("#L" + targetLine).get(0).scrollIntoView();
};
/**
* Initialise the JSON validator page.
*/
var init = function () {
- // code formatting
+ // set initial code formatting
+ selection.parseFromUrlHash(location.hash);
formatCode();
+ scrollToRange();
+
+ // update code formatting on hash change
+ $(window).on("hashchange", function() {
+ selection.parseFromUrlHash(location.hash);
+ formatCode();
+ scrollToRange();
+ });
// change format
$("#output #format").on("change", function() {