diff --git a/erpnext/public/js/shop_floor/shop_floor.js b/erpnext/public/js/shop_floor/shop_floor.js
index a595102c004..4495c825169 100644
--- a/erpnext/public/js/shop_floor/shop_floor.js
+++ b/erpnext/public/js/shop_floor/shop_floor.js
@@ -356,7 +356,7 @@ class ShopFloor {
// Hero image = the current operation's workstation. No item-image fallback — when the
// workstation has no image uploaded we show its initials, never the product image.
const image = wo.workstation_image
- ? `
`
+ ? `
`
: `${frappe.get_abbr(wo.workstation_name || item, 2)}`;
const workstation_line = wo.workstation_name
@@ -370,7 +370,9 @@ class ShopFloor {
const wip_pct = Math.min(cint(wo.per_in_progress), 100 - done_pct);
return `
-
+
${image}
@@ -378,7 +380,9 @@ class ShopFloor {
${workstation_line}
@@ -405,7 +409,7 @@ class ShopFloor {
this.board_container
.find(".sf-wo-card")
.removeClass("sf-selected")
- .filter(`[data-name="${name}"]`)
+ .filter(`[data-name="${$.escapeSelector(name)}"]`)
.addClass("sf-selected");
// The detail pane reuses the operator rendering for a single work order.
this.detail_container.html(`
@@ -414,7 +418,9 @@ class ShopFloor {
"Back"
)} (Esc)
${frappe.utils.escape_html(name)}
-
${__("Open")}
+
${__(
+ "Open"
+ )}
`);
@@ -1235,7 +1241,7 @@ class ShopFloor {
const pad = (n) => (n < 10 ? "0" + n : String(n));
const scope = $container || this.wrapper;
- const timer = scope.find(`.mes-job-timer[data-job-card="${jc_name}"]`);
+ const timer = scope.find(`.mes-job-timer[data-job-card="${$.escapeSelector(jc_name)}"]`);
timer.find(".h").text(pad(h));
timer.find(".m").text(pad(m));
timer.find(".s").text(pad(s));