diff --git a/src/js/gcode-viewer.js b/src/js/gcode-viewer.js
index db2ef44..6f2a004 100644
--- a/src/js/gcode-viewer.js
+++ b/src/js/gcode-viewer.js
@@ -1,152 +1,162 @@
"use strict";
const entityMap = {
- "&": "&", "<": "<", ">": ">", '"': """, "'": "'",
- "/": "/", "`": "`", "=": "=" };
+ "&": "&",
+ "<": "<",
+ ">": ">",
+ '"': """,
+ "'": "'",
+ "/": "/",
+ "`": "`",
+ "=": "=",
+};
function escapeHTML(s) {
- return s.replace(/[&<>"'`=\\/]/g, function(c) {
- return entityMap[c];
- });
+ return s.replace(/[&<>"'`=\\/]/g, function (c) {
+ return entityMap[c];
+ });
}
module.exports = {
- template: "#gcode-viewer-template",
+ template: "#gcode-viewer-template",
- data: function() {
- return {
- empty: true,
- file: "",
- line: -1
- };
+ data: function () {
+ return {
+ empty: true,
+ file: "",
+ line: -1,
+ };
+ },
+
+ events: {
+ "gcode-load": function (file) {
+ this.load(file);
},
-
- events: {
- "gcode-load": function(file) {
- this.load(file);
- },
- "gcode-clear": function() {
- this.clear();
- },
- "gcode-reload": function(file) {
- this.reload(file);
- },
- "gcode-line": function(line) {
- this.update_line(line);
- }
+ "gcode-clear": function () {
+ this.clear();
},
-
- ready: function() {
- this.clusterize = new Clusterize({
- rows: [],
- scrollElem: this.$el.querySelector(".clusterize-scroll"),
- contentElem: this.$el.querySelector(".clusterize-content"),
- no_data_text: "GCode view...",
- callbacks: { clusterChanged: this.highlight }
- });
+ "gcode-reload": function (file) {
+ this.reload(file);
},
-
- attached: function() {
- if (typeof this.clusterize != "undefined") {
- this.clusterize.refresh(true);
- }
+ "gcode-line": function (line) {
+ this.update_line(line);
},
+ },
- methods: {
- load: async function(file) {
- if (file == this.file) {
- return;
- }
+ ready: function () {
+ this.clusterize = new Clusterize({
+ rows: [],
+ scrollElem: this.$el.querySelector(".clusterize-scroll"),
+ contentElem: this.$el.querySelector(".clusterize-content"),
+ no_data_text: "GCode view...",
+ callbacks: { clusterChanged: this.highlight },
+ });
+ },
- this.clear();
- this.file = file;
- if (!file) {
- return;
- }
-
- const response = await fetch(`/api/file/${file}`, { cache: "no-cache" });
- const text = await response.text();
-
- if (text.length > 20e6) {
- this.clusterize.update([ "File is large - gcode view disabled" ]);
- } else {
- const lines = escapeHTML(text.trimRight())
- .split(/[\r\n]/)
- .map((line, i) => `
${i + 1}${line}`);
-
- this.clusterize.update(lines);
- }
-
- this.empty = false;
-
- Vue.nextTick(this.update_line);
- },
-
- clear: function() {
- this.empty = true;
- this.file = "";
- this.line = -1;
- this.clusterize.clear();
- },
-
- reload: function(file) {
- if (file != this.file) {
- return;
- }
- this.clear();
- this.load(file);
- },
-
- highlight: function() {
- const highlights = this.$el.querySelectorAll(".highlight");
- for (const highlight of highlights) {
- highlight.className = (highlight.className || "")
- .split(" ")
- .filter(c => c !== "highlight")
- .join(" ");
- }
-
- const lines = this.$el.querySelectorAll(`.ln${this.line}`);
- for (const line of lines) {
- line.className = (line.className || "")
- .split(" ")
- .filter(c => c !== "highlight")
- .concat([ "highlight" ])
- .join(" ");
- }
- },
-
- update_line: function(line) {
- if (typeof line != "undefined") {
- if (this.line == line) {
- return;
- }
-
- this.line = line;
- } else {
- line = this.line;
- }
-
- const totalLines = this.clusterize.getRowsAmount();
-
- if (line <= 0) {
- line = 1;
- }
-
- if (totalLines < line) {
- line = totalLines;
- }
-
- const scroll = this.$el.querySelector(".clusterize-scroll");
-
- const lineHeight = scroll.scrollHeight / totalLines;
- const linesPerPage = Math.floor(scroll.clientHeight / lineHeight);
- const target = line - 1 - Math.floor(linesPerPage / 2);
-
- // Update scroll position
- scroll.scrollTop = target * lineHeight;
-
- Vue.nextTick(this.highlight);
- }
+ attached: function () {
+ if (typeof this.clusterize != "undefined") {
+ this.clusterize.refresh(true);
}
+ },
+
+ methods: {
+ load: async function (file) {
+ if (file == this.file) {
+ return;
+ }
+
+ this.clear();
+ this.file = file;
+ if (!file) {
+ return;
+ }
+
+ const response = await fetch(`/api/file/${file}`, { cache: "no-cache" });
+ if (response.status == 400) {
+ return;
+ }
+ const text = await response.text();
+
+ if (text.length > 20e6) {
+ this.clusterize.update(["File is large - gcode view disabled"]);
+ } else {
+ const lines = escapeHTML(text.trimRight())
+ .split(/[\r\n]/)
+ .map((line, i) => `${i + 1}${line}`);
+
+ this.clusterize.update(lines);
+ }
+
+ this.empty = false;
+
+ Vue.nextTick(this.update_line);
+ },
+
+ clear: function () {
+ this.empty = true;
+ this.file = "";
+ this.line = -1;
+ this.clusterize.clear();
+ },
+
+ reload: function (file) {
+ if (file != this.file) {
+ return;
+ }
+ this.clear();
+ this.load(file);
+ },
+
+ highlight: function () {
+ const highlights = this.$el.querySelectorAll(".highlight");
+ for (const highlight of highlights) {
+ highlight.className = (highlight.className || "")
+ .split(" ")
+ .filter(c => c !== "highlight")
+ .join(" ");
+ }
+
+ const lines = this.$el.querySelectorAll(`.ln${this.line}`);
+ for (const line of lines) {
+ line.className = (line.className || "")
+ .split(" ")
+ .filter(c => c !== "highlight")
+ .concat(["highlight"])
+ .join(" ");
+ }
+ },
+
+ update_line: function (line) {
+ if (typeof line != "undefined") {
+ if (this.line == line) {
+ return;
+ }
+
+ this.line = line;
+ } else {
+ line = this.line;
+ }
+
+ const totalLines = this.clusterize.getRowsAmount();
+
+ if (line <= 0) {
+ line = 1;
+ }
+
+ if (totalLines < line) {
+ line = totalLines;
+ }
+
+ const scroll = this.$el.querySelector(".clusterize-scroll");
+
+ const lineHeight = scroll.scrollHeight / totalLines;
+ const linesPerPage = Math.floor(scroll.clientHeight / lineHeight);
+ const target = line - 1 - Math.floor(linesPerPage / 2);
+
+ // Update scroll position
+ scroll.scrollTop = target * lineHeight;
+
+ Vue.nextTick(this.highlight);
+ },
+ },
};