From fc1c47be104d9e78ca5f5b61cb60e34a4de1dce4 Mon Sep 17 00:00:00 2001 From: lijyze Date: Wed, 15 Jun 2022 11:59:13 +0800 Subject: [PATCH 1/3] Ignore single-line highlight which is out of range --- plugins/line-highlight/index.html | 2 +- .../line-highlight/prism-line-highlight.js | 21 +++++++++++++++---- .../prism-line-highlight.min.js | 2 +- 3 files changed, 19 insertions(+), 6 deletions(-) diff --git a/plugins/line-highlight/index.html b/plugins/line-highlight/index.html index f06b5a53a1..996dcf7cdc 100644 --- a/plugins/line-highlight/index.html +++ b/plugins/line-highlight/index.html @@ -77,7 +77,7 @@

Compatible with Line numbers


 
 	

Even with some extra content before the code element.

-
Some content

+
Some content

With linkable line numbers

diff --git a/plugins/line-highlight/prism-line-highlight.js b/plugins/line-highlight/prism-line-highlight.js index 1e615c2f49..347579b2bf 100644 --- a/plugins/line-highlight/prism-line-highlight.js +++ b/plugins/line-highlight/prism-line-highlight.js @@ -168,6 +168,13 @@ if (hasLineNumbers && Prism.plugins.lineNumbers) { var startNode = Prism.plugins.lineNumbers.getLine(pre, start); var endNode = Prism.plugins.lineNumbers.getLine(pre, end); + // endNode is the `nthChild` th child of its parent node + var nthChild = 1; + var element = endNode; + while (element.previousSibling) { + element = element.previousSibling; + nthChild++; + } if (startNode) { var top = startNode.offsetTop + codePreOffset + 'px'; @@ -177,10 +184,16 @@ } if (endNode) { - var height = (endNode.offsetTop - startNode.offsetTop) + endNode.offsetHeight + 'px'; - mutateActions.push(function () { - line.style.height = height; - }); + // Ignore the line if it exceed range + if (start === end && end > nthChild) { + mutateActions.pop(); + return; + } else { + var height = (endNode.offsetTop - startNode.offsetTop) + endNode.offsetHeight + 'px'; + mutateActions.push(function () { + line.style.height = height; + }); + } } } else { mutateActions.push(function () { diff --git a/plugins/line-highlight/prism-line-highlight.min.js b/plugins/line-highlight/prism-line-highlight.min.js index 7d38b6b424..703c5a75bf 100644 --- a/plugins/line-highlight/prism-line-highlight.min.js +++ b/plugins/line-highlight/prism-line-highlight.min.js @@ -1 +1 @@ -!function(){if("undefined"!=typeof Prism&&"undefined"!=typeof document&&document.querySelector){var e,t="line-numbers",i="linkable-line-numbers",n=!0;Prism.plugins.lineHighlight={highlightLines:function(r,a,u){var c=(a="string"==typeof a?a:r.getAttribute("data-line")||"").replace(/\s+/g,"").split(",").filter(Boolean),d=+r.getAttribute("data-line-offset")||0,h=(function(){if(void 0===e){var t=document.createElement("div");t.style.fontSize="13px",t.style.lineHeight="1.5",t.style.padding="0",t.style.border="0",t.innerHTML=" 
 ",document.body.appendChild(t),e=38===t.offsetHeight,document.body.removeChild(t)}return e}()?parseInt:parseFloat)(getComputedStyle(r).lineHeight),f=Prism.util.isActive(r,t),p=r.querySelector("code"),g=f?r:p||r,m=[],v=p&&g!=p?function(e,t){var i=getComputedStyle(e),n=getComputedStyle(t);function r(e){return+e.substr(0,e.length-2)}return t.offsetTop+r(n.borderTopWidth)+r(n.paddingTop)-r(i.paddingTop)}(r,p):0;c.forEach((function(e){var t=e.split("-"),i=+t[0],n=+t[1]||i,o=r.querySelector('.line-highlight[data-range="'+e+'"]')||document.createElement("div");if(m.push((function(){o.setAttribute("aria-hidden","true"),o.setAttribute("data-range",e),o.className=(u||"")+" line-highlight"})),f&&Prism.plugins.lineNumbers){var s=Prism.plugins.lineNumbers.getLine(r,i),l=Prism.plugins.lineNumbers.getLine(r,n);if(s){var a=s.offsetTop+v+"px";m.push((function(){o.style.top=a}))}if(l){var c=l.offsetTop-s.offsetTop+l.offsetHeight+"px";m.push((function(){o.style.height=c}))}}else m.push((function(){o.setAttribute("data-start",String(i)),n>i&&o.setAttribute("data-end",String(n)),o.style.top=(i-d-1)*h+v+"px",o.textContent=new Array(n-i+2).join(" \n")}));m.push((function(){o.style.width=r.scrollWidth+"px"})),m.push((function(){g.appendChild(o)}))}));var y=r.id;if(f&&Prism.util.isActive(r,i)&&y){s(r,i)||m.push((function(){r.classList.add(i)}));var b=parseInt(r.getAttribute("data-start")||"1");o(".line-numbers-rows > span",r).forEach((function(e,t){var i=t+b;e.onclick=function(){var e=y+"."+i;n=!1,location.hash=e,setTimeout((function(){n=!0}),1)}}))}return function(){m.forEach(l)}}};var r=0;Prism.hooks.add("before-sanity-check",(function(e){var t=e.element.parentElement;if(a(t)){var i=0;o(".line-highlight",t).forEach((function(e){i+=e.textContent.length,e.parentNode.removeChild(e)})),i&&/^(?: \n)+$/.test(e.code.slice(-i))&&(e.code=e.code.slice(0,-i))}})),Prism.hooks.add("complete",(function e(i){var n=i.element.parentElement;if(a(n)){clearTimeout(r);var o=Prism.plugins.lineNumbers,l=i.plugins&&i.plugins.lineNumbers;s(n,t)&&o&&!l?Prism.hooks.add("line-numbers",e):(Prism.plugins.lineHighlight.highlightLines(n)(),r=setTimeout(u,1))}})),window.addEventListener("hashchange",u),window.addEventListener("resize",(function(){o("pre").filter(a).map((function(e){return Prism.plugins.lineHighlight.highlightLines(e)})).forEach(l)}))}function o(e,t){return Array.prototype.slice.call((t||document).querySelectorAll(e))}function s(e,t){return e.classList.contains(t)}function l(e){e()}function a(e){return!!(e&&/pre/i.test(e.nodeName)&&(e.hasAttribute("data-line")||e.id&&Prism.util.isActive(e,i)))}function u(){var e=location.hash.slice(1);o(".temporary.line-highlight").forEach((function(e){e.parentNode.removeChild(e)}));var t=(e.match(/\.([\d,-]+)$/)||[,""])[1];if(t&&!document.getElementById(e)){var i=e.slice(0,e.lastIndexOf(".")),r=document.getElementById(i);r&&(r.hasAttribute("data-line")||r.setAttribute("data-line",""),Prism.plugins.lineHighlight.highlightLines(r,t,"temporary ")(),n&&document.querySelector(".temporary.line-highlight").scrollIntoView())}}}(); \ No newline at end of file +!function(){if("undefined"!=typeof Prism&&"undefined"!=typeof document&&document.querySelector){var e,t="line-numbers",i="linkable-line-numbers",n=!0;Prism.plugins.lineHighlight={highlightLines:function(r,u,a){var c=(u="string"==typeof u?u:r.getAttribute("data-line")||"").replace(/\s+/g,"").split(",").filter(Boolean),d=+r.getAttribute("data-line-offset")||0,h=(function(){if(void 0===e){var t=document.createElement("div");t.style.fontSize="13px",t.style.lineHeight="1.5",t.style.padding="0",t.style.border="0",t.innerHTML=" 
 ",document.body.appendChild(t),e=38===t.offsetHeight,document.body.removeChild(t)}return e}()?parseInt:parseFloat)(getComputedStyle(r).lineHeight),p=Prism.util.isActive(r,t),f=r.querySelector("code"),g=p?r:f||r,m=[],v=f&&g!=f?function(e,t){var i=getComputedStyle(e),n=getComputedStyle(t);function r(e){return+e.substr(0,e.length-2)}return t.offsetTop+r(n.borderTopWidth)+r(n.paddingTop)-r(i.paddingTop)}(r,f):0;c.forEach((function(e){var t=e.split("-"),i=+t[0],n=+t[1]||i,o=r.querySelector('.line-highlight[data-range="'+e+'"]')||document.createElement("div");if(m.push((function(){o.setAttribute("aria-hidden","true"),o.setAttribute("data-range",e),o.className=(a||"")+" line-highlight"})),p&&Prism.plugins.lineNumbers){for(var s=Prism.plugins.lineNumbers.getLine(r,i),l=Prism.plugins.lineNumbers.getLine(r,n),u=1,c=l;c.previousSibling;)c=c.previousSibling,u++;if(s){var f=s.offsetTop+v+"px";m.push((function(){o.style.top=f}))}if(l){if(i===n&&n>u)return void m.pop();var b=l.offsetTop-s.offsetTop+l.offsetHeight+"px";m.push((function(){o.style.height=b}))}}else m.push((function(){o.setAttribute("data-start",String(i)),n>i&&o.setAttribute("data-end",String(n)),o.style.top=(i-d-1)*h+v+"px",o.textContent=new Array(n-i+2).join(" \n")}));m.push((function(){o.style.width=r.scrollWidth+"px"})),m.push((function(){g.appendChild(o)}))}));var b=r.id;if(p&&Prism.util.isActive(r,i)&&b){s(r,i)||m.push((function(){r.classList.add(i)}));var y=parseInt(r.getAttribute("data-start")||"1");o(".line-numbers-rows > span",r).forEach((function(e,t){var i=t+y;e.onclick=function(){var e=b+"."+i;n=!1,location.hash=e,setTimeout((function(){n=!0}),1)}}))}return function(){m.forEach(l)}}};var r=0;Prism.hooks.add("before-sanity-check",(function(e){var t=e.element.parentElement;if(u(t)){var i=0;o(".line-highlight",t).forEach((function(e){i+=e.textContent.length,e.parentNode.removeChild(e)})),i&&/^(?: \n)+$/.test(e.code.slice(-i))&&(e.code=e.code.slice(0,-i))}})),Prism.hooks.add("complete",(function e(i){var n=i.element.parentElement;if(u(n)){clearTimeout(r);var o=Prism.plugins.lineNumbers,l=i.plugins&&i.plugins.lineNumbers;s(n,t)&&o&&!l?Prism.hooks.add("line-numbers",e):(Prism.plugins.lineHighlight.highlightLines(n)(),r=setTimeout(a,1))}})),window.addEventListener("hashchange",a),window.addEventListener("resize",(function(){o("pre").filter(u).map((function(e){return Prism.plugins.lineHighlight.highlightLines(e)})).forEach(l)}))}function o(e,t){return Array.prototype.slice.call((t||document).querySelectorAll(e))}function s(e,t){return e.classList.contains(t)}function l(e){e()}function u(e){return!!(e&&/pre/i.test(e.nodeName)&&(e.hasAttribute("data-line")||e.id&&Prism.util.isActive(e,i)))}function a(){var e=location.hash.slice(1);o(".temporary.line-highlight").forEach((function(e){e.parentNode.removeChild(e)}));var t=(e.match(/\.([\d,-]+)$/)||[,""])[1];if(t&&!document.getElementById(e)){var i=e.slice(0,e.lastIndexOf(".")),r=document.getElementById(i);r&&(r.hasAttribute("data-line")||r.setAttribute("data-line",""),Prism.plugins.lineHighlight.highlightLines(r,t,"temporary ")(),n&&document.querySelector(".temporary.line-highlight").scrollIntoView())}}}(); \ No newline at end of file From a94d6a583d14e41e546f08ae18d1395b84ae4fe3 Mon Sep 17 00:00:00 2001 From: lijyze Date: Wed, 15 Jun 2022 12:21:08 +0800 Subject: [PATCH 2/3] Ignore single-line highlight which is out of range --- plugins/line-highlight/index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/line-highlight/index.html b/plugins/line-highlight/index.html index 996dcf7cdc..f06b5a53a1 100644 --- a/plugins/line-highlight/index.html +++ b/plugins/line-highlight/index.html @@ -77,7 +77,7 @@

Compatible with Line numbers


 
 	

Even with some extra content before the code element.

-
Some content

+
Some content

With linkable line numbers

From 0240cd69bbf2f30dfd2f9044d39671b7d8b6747e Mon Sep 17 00:00:00 2001 From: lijyze Date: Thu, 16 Jun 2022 12:01:13 +0800 Subject: [PATCH 3/3] Ignore out-of-range part of ranges --- .../line-highlight/prism-line-highlight.js | 30 ++++++++----------- .../prism-line-highlight.min.js | 2 +- 2 files changed, 13 insertions(+), 19 deletions(-) diff --git a/plugins/line-highlight/prism-line-highlight.js b/plugins/line-highlight/prism-line-highlight.js index 347579b2bf..4b3a09eb40 100644 --- a/plugins/line-highlight/prism-line-highlight.js +++ b/plugins/line-highlight/prism-line-highlight.js @@ -6,6 +6,7 @@ var LINE_NUMBERS_CLASS = 'line-numbers'; var LINKABLE_LINE_NUMBERS_CLASS = 'linkable-line-numbers'; + var NEW_LINE_EXP = /\n(?!$)/g; /** * @param {string} selector @@ -136,7 +137,8 @@ var codeElement = pre.querySelector('code'); var parentElement = hasLineNumbers ? pre : codeElement || pre; var mutateActions = /** @type {(() => void)[]} */ ([]); - + var lineBreakMatch = codeElement.textContent.match(NEW_LINE_EXP); + var numberOfLines = lineBreakMatch ? lineBreakMatch.length + 1 : 1; /** * The top offset between the content box of the element and the content box of the parent element of * the line highlight element (either `
` or ``).
@@ -154,6 +156,11 @@
 
 				var start = +range[0];
 				var end = +range[1] || start;
+				end = Math.min(numberOfLines, end);
+
+				if (end < start) {
+					return;
+				}
 
 				/** @type {HTMLElement} */
 				var line = pre.querySelector('.line-highlight[data-range="' + currentRange + '"]') || document.createElement('div');
@@ -168,13 +175,6 @@
 				if (hasLineNumbers && Prism.plugins.lineNumbers) {
 					var startNode = Prism.plugins.lineNumbers.getLine(pre, start);
 					var endNode = Prism.plugins.lineNumbers.getLine(pre, end);
-					// endNode is the `nthChild` th child of its parent node
-					var nthChild = 1;
-					var element = endNode;
-					while (element.previousSibling) {
-						element = element.previousSibling;
-						nthChild++;
-					}
 
 					if (startNode) {
 						var top = startNode.offsetTop + codePreOffset + 'px';
@@ -184,16 +184,10 @@
 					}
 
 					if (endNode) {
-						// Ignore the line if it exceed range
-						if (start === end && end > nthChild) {
-							mutateActions.pop();
-							return;
-						} else {
-							var height = (endNode.offsetTop - startNode.offsetTop) + endNode.offsetHeight + 'px';
-							mutateActions.push(function () {
-								line.style.height = height;
-							});
-						}
+						var height = (endNode.offsetTop - startNode.offsetTop) + endNode.offsetHeight + 'px';
+						mutateActions.push(function () {
+							line.style.height = height;
+						});
 					}
 				} else {
 					mutateActions.push(function () {
diff --git a/plugins/line-highlight/prism-line-highlight.min.js b/plugins/line-highlight/prism-line-highlight.min.js
index 703c5a75bf..ade269d855 100644
--- a/plugins/line-highlight/prism-line-highlight.min.js
+++ b/plugins/line-highlight/prism-line-highlight.min.js
@@ -1 +1 @@
-!function(){if("undefined"!=typeof Prism&&"undefined"!=typeof document&&document.querySelector){var e,t="line-numbers",i="linkable-line-numbers",n=!0;Prism.plugins.lineHighlight={highlightLines:function(r,u,a){var c=(u="string"==typeof u?u:r.getAttribute("data-line")||"").replace(/\s+/g,"").split(",").filter(Boolean),d=+r.getAttribute("data-line-offset")||0,h=(function(){if(void 0===e){var t=document.createElement("div");t.style.fontSize="13px",t.style.lineHeight="1.5",t.style.padding="0",t.style.border="0",t.innerHTML=" 
 ",document.body.appendChild(t),e=38===t.offsetHeight,document.body.removeChild(t)}return e}()?parseInt:parseFloat)(getComputedStyle(r).lineHeight),p=Prism.util.isActive(r,t),f=r.querySelector("code"),g=p?r:f||r,m=[],v=f&&g!=f?function(e,t){var i=getComputedStyle(e),n=getComputedStyle(t);function r(e){return+e.substr(0,e.length-2)}return t.offsetTop+r(n.borderTopWidth)+r(n.paddingTop)-r(i.paddingTop)}(r,f):0;c.forEach((function(e){var t=e.split("-"),i=+t[0],n=+t[1]||i,o=r.querySelector('.line-highlight[data-range="'+e+'"]')||document.createElement("div");if(m.push((function(){o.setAttribute("aria-hidden","true"),o.setAttribute("data-range",e),o.className=(a||"")+" line-highlight"})),p&&Prism.plugins.lineNumbers){for(var s=Prism.plugins.lineNumbers.getLine(r,i),l=Prism.plugins.lineNumbers.getLine(r,n),u=1,c=l;c.previousSibling;)c=c.previousSibling,u++;if(s){var f=s.offsetTop+v+"px";m.push((function(){o.style.top=f}))}if(l){if(i===n&&n>u)return void m.pop();var b=l.offsetTop-s.offsetTop+l.offsetHeight+"px";m.push((function(){o.style.height=b}))}}else m.push((function(){o.setAttribute("data-start",String(i)),n>i&&o.setAttribute("data-end",String(n)),o.style.top=(i-d-1)*h+v+"px",o.textContent=new Array(n-i+2).join(" \n")}));m.push((function(){o.style.width=r.scrollWidth+"px"})),m.push((function(){g.appendChild(o)}))}));var b=r.id;if(p&&Prism.util.isActive(r,i)&&b){s(r,i)||m.push((function(){r.classList.add(i)}));var y=parseInt(r.getAttribute("data-start")||"1");o(".line-numbers-rows > span",r).forEach((function(e,t){var i=t+y;e.onclick=function(){var e=b+"."+i;n=!1,location.hash=e,setTimeout((function(){n=!0}),1)}}))}return function(){m.forEach(l)}}};var r=0;Prism.hooks.add("before-sanity-check",(function(e){var t=e.element.parentElement;if(u(t)){var i=0;o(".line-highlight",t).forEach((function(e){i+=e.textContent.length,e.parentNode.removeChild(e)})),i&&/^(?: \n)+$/.test(e.code.slice(-i))&&(e.code=e.code.slice(0,-i))}})),Prism.hooks.add("complete",(function e(i){var n=i.element.parentElement;if(u(n)){clearTimeout(r);var o=Prism.plugins.lineNumbers,l=i.plugins&&i.plugins.lineNumbers;s(n,t)&&o&&!l?Prism.hooks.add("line-numbers",e):(Prism.plugins.lineHighlight.highlightLines(n)(),r=setTimeout(a,1))}})),window.addEventListener("hashchange",a),window.addEventListener("resize",(function(){o("pre").filter(u).map((function(e){return Prism.plugins.lineHighlight.highlightLines(e)})).forEach(l)}))}function o(e,t){return Array.prototype.slice.call((t||document).querySelectorAll(e))}function s(e,t){return e.classList.contains(t)}function l(e){e()}function u(e){return!!(e&&/pre/i.test(e.nodeName)&&(e.hasAttribute("data-line")||e.id&&Prism.util.isActive(e,i)))}function a(){var e=location.hash.slice(1);o(".temporary.line-highlight").forEach((function(e){e.parentNode.removeChild(e)}));var t=(e.match(/\.([\d,-]+)$/)||[,""])[1];if(t&&!document.getElementById(e)){var i=e.slice(0,e.lastIndexOf(".")),r=document.getElementById(i);r&&(r.hasAttribute("data-line")||r.setAttribute("data-line",""),Prism.plugins.lineHighlight.highlightLines(r,t,"temporary ")(),n&&document.querySelector(".temporary.line-highlight").scrollIntoView())}}}(); \ No newline at end of file +!function(){if("undefined"!=typeof Prism&&"undefined"!=typeof document&&document.querySelector){var e,t="line-numbers",i="linkable-line-numbers",n=/\n(?!$)/g,r=!0;Prism.plugins.lineHighlight={highlightLines:function(o,u,c){var h=(u="string"==typeof u?u:o.getAttribute("data-line")||"").replace(/\s+/g,"").split(",").filter(Boolean),d=+o.getAttribute("data-line-offset")||0,f=(function(){if(void 0===e){var t=document.createElement("div");t.style.fontSize="13px",t.style.lineHeight="1.5",t.style.padding="0",t.style.border="0",t.innerHTML=" 
 ",document.body.appendChild(t),e=38===t.offsetHeight,document.body.removeChild(t)}return e}()?parseInt:parseFloat)(getComputedStyle(o).lineHeight),p=Prism.util.isActive(o,t),g=o.querySelector("code"),m=p?o:g||o,v=[],y=g.textContent.match(n),b=y?y.length+1:1,A=g&&m!=g?function(e,t){var i=getComputedStyle(e),n=getComputedStyle(t);function r(e){return+e.substr(0,e.length-2)}return t.offsetTop+r(n.borderTopWidth)+r(n.paddingTop)-r(i.paddingTop)}(o,g):0;h.forEach((function(e){var t=e.split("-"),i=+t[0],n=+t[1]||i;if(!((n=Math.min(b,n))i&&r.setAttribute("data-end",String(n)),r.style.top=(i-d-1)*f+A+"px",r.textContent=new Array(n-i+2).join(" \n")}));v.push((function(){r.style.width=o.scrollWidth+"px"})),v.push((function(){m.appendChild(r)}))}}));var P=o.id;if(p&&Prism.util.isActive(o,i)&&P){l(o,i)||v.push((function(){o.classList.add(i)}));var E=parseInt(o.getAttribute("data-start")||"1");s(".line-numbers-rows > span",o).forEach((function(e,t){var i=t+E;e.onclick=function(){var e=P+"."+i;r=!1,location.hash=e,setTimeout((function(){r=!0}),1)}}))}return function(){v.forEach(a)}}};var o=0;Prism.hooks.add("before-sanity-check",(function(e){var t=e.element.parentElement;if(u(t)){var i=0;s(".line-highlight",t).forEach((function(e){i+=e.textContent.length,e.parentNode.removeChild(e)})),i&&/^(?: \n)+$/.test(e.code.slice(-i))&&(e.code=e.code.slice(0,-i))}})),Prism.hooks.add("complete",(function e(i){var n=i.element.parentElement;if(u(n)){clearTimeout(o);var r=Prism.plugins.lineNumbers,s=i.plugins&&i.plugins.lineNumbers;l(n,t)&&r&&!s?Prism.hooks.add("line-numbers",e):(Prism.plugins.lineHighlight.highlightLines(n)(),o=setTimeout(c,1))}})),window.addEventListener("hashchange",c),window.addEventListener("resize",(function(){s("pre").filter(u).map((function(e){return Prism.plugins.lineHighlight.highlightLines(e)})).forEach(a)}))}function s(e,t){return Array.prototype.slice.call((t||document).querySelectorAll(e))}function l(e,t){return e.classList.contains(t)}function a(e){e()}function u(e){return!!(e&&/pre/i.test(e.nodeName)&&(e.hasAttribute("data-line")||e.id&&Prism.util.isActive(e,i)))}function c(){var e=location.hash.slice(1);s(".temporary.line-highlight").forEach((function(e){e.parentNode.removeChild(e)}));var t=(e.match(/\.([\d,-]+)$/)||[,""])[1];if(t&&!document.getElementById(e)){var i=e.slice(0,e.lastIndexOf(".")),n=document.getElementById(i);n&&(n.hasAttribute("data-line")||n.setAttribute("data-line",""),Prism.plugins.lineHighlight.highlightLines(n,t,"temporary ")(),r&&document.querySelector(".temporary.line-highlight").scrollIntoView())}}}(); \ No newline at end of file