is-html-attribute-closing
Version:
Is a character on a given index a closing of an HTML attribute?
11 lines (9 loc) • 5.14 kB
JavaScript
/**
* @name is-html-attribute-closing
* @fileoverview Is a character on a given index a closing of an HTML attribute?
* @version 4.0.23
* @author Roy Revelt, Codsen Ltd
* @license MIT
* {@link https://codsen.com/os/is-html-attribute-closing/}
*/
import{allHtmlAttribs as r}from"html-all-known-attributes";import{isAttrNameChar as p}from"is-char-suitable-for-html-attr-name";import{left as Y,right as v}from"string-left-right";import{matchRight as j}from"string-match-left-right";import{isAttrNameChar as W}from"is-char-suitable-for-html-attr-name";import{left as H}from"string-left-right";function T(e){return e==="'"?'"':"'"}function M(e,l,u,i=[]){for(let b=l,o=e.length;b<o;b++){if(i.some($=>e.startsWith($,b)))return!0;if(e[b]===u)return!1}return!0}function q(e,l,u,i){for(let b=l,o=e.length;b<o;b++){if(e.startsWith(u,b))return!0;if(e.startsWith(i,b))return!1}return!1}function U(e,l){return!W(e[l])||!l?!1:/^[a-zA-Z0-9:-]*(\s*[=]?\s*((?:'[^']*')|(?:"[^"]*")))|( [^/>'"=]*['"])/.test(e.slice(l))}function L(e,l){return!l||!W(e[l])?!1:/^[a-zA-Z0-9:-]*=(((?:'[^']*')|(?:"[^"]*"))|((?:['"][^'"]*['"]\s*\/?>)))/.test(e.slice(l))}function P(e,l){if(W(e[H(e,l)])){for(let u=l;u--;)if(e[u].trim().length&&!W(e[u]))return e.slice(u+1,l)}}var X="4.0.23";var $e=X;function ne(e,l,u){if(typeof e!="string"||!e.trim()||!Number.isInteger(l)||!Number.isInteger(u)||!e[l]||!e[u]||l>=u)return!1;let i=`'"`.includes(e[l])?e[l]:null,b=null;i&&(b=T(i));let o,$=new Map().set("'",0).set('"',0).set("matchedPairs",0),s=null,d=0,h=!1,E,N,a,S,F=!1,Q=!1,w=!1;for(let t=l,O=e.length;t<O;t++){let c=v(e,t),B=Y(e,t);if(`'"`.includes(e[t])&&h&&E===l&&N!==void 0&&N<t&&t>=u){let m=t!==u||L(e,v(e,u))||"/>".includes(e[c]),n=!(t>u&&e[l]===e[u]&&e[l]===e[t]&&U(e,t+1)),g=t===u&&U(e,u+1),f=o&&o<t&&r.has(e.slice(o,t).trim()),D;o&&(D=e.slice(o,t).trim());let R=o&&o<t&&e[o-1]&&!e[o-1].trim()&&Array.from(e.slice(o,t).trim()).every(z=>p(z))&&e[l]===e[u]&&!"/>".includes(e[c])&&M(e,t+1,"=",["'",'"']),V;t===u&&(V=P(e,t));let A=t===u&&(!p(e[B])||V&&!r.has(V))&&e[B]!=="=",C="/>".includes(e[c])&&t===u,k=p(e[c]),J=h&&t!==u,y=!(t>=u&&e[Y(e,u)]===":");return!!(m&&n&&(g||f||R||A)&&(C||k||J)&&y)}if(`'"`.includes(e[t])){if(e[t]==="'"&&e[t-1]==='"'&&e[t+1]==='"'||e[t]==='"'&&e[t-1]==="'"&&e[t+1]==="'")continue;s&&e[t]===e[s]?($.set("matchedPairs",+$.get("matchedPairs")+1),E=s,N=t,s=null,h=!0):h=!1,$.set(e[t],+$.get(e[t])+1),d=+$.get('"')+ +$.get("'")}if(e[t]===">"&&!Q&&(Q=!0,d&&$.get("matchedPairs")&&d===$.get("matchedPairs")*2&&t<u))return!1;if(e[t]==="<"&&e[c]!=="%"&&Q&&!w)return w=!0,!1;if(e[t].trim()&&!o)p(e[t])&&(o=t);else if(o&&!p(e[t])){if(S=a,a=e.slice(o,t),F=o>=u,`'"`.includes(e[t])&&$.get("matchedPairs")===0&&d===3&&e[l]===e[t]&&r.has(a)&&!`'"`.includes(e[c])){let m=t>u,n=!s,g=s+1>=t,f=e.slice(s+1,t).trim().split(/\s+/).every(y=>r.has(y)),D=!a||!S?.endsWith(":"),R=t===u,V=d<3,A=!!h,C=!s,k=s+1>=t,J=!e.slice(s+1,t).trim().split(/\s+/).every(y=>r.has(y));return m&&(n||g||f)&&D||R&&(V||A||C||k||J)}if(a&&r.has(a)&&E===l&&N===u)return!0}if(`'"`.includes(e[t])&&(!($.get('"')%2)||!($.get("'")%2))&&(+$.get('"')+ +$.get("'"))%2&&(a&&r.has(a)||t>u+1&&r.has(e.slice(u+1,t).trim()))&&!(e[t+1]===e[t]&&e[t]===e[l])&&!(t>u+1&&e[Y(e,u)]===":")&&!(a&&S?.trim().endsWith(":"))){let m=t>u,n=!!i,g=e[l]!==e[u],f=r.has(e.slice(l+1,u).trim()),D=!q(e,t+1,e[u],T(e[u]));return m&&!(n&&g&&f&&D)}if((e[t]==="="||!e[t].length&&e[c]==="=")&&a&&r.has(a)){let m=t>u,n=!(!(h&&E===l&&N===u||L(e,o))&&h&&E!==void 0&&E<=u);return m&&n}if(t>u){if(i&&e[t]===i){let m=!!s,n=s===u,g=s+1<t&&e.slice(s+1,t).trim(),f=e.slice(s+1,t).trim().split(/\s+/).every(V=>r.has(V)),D=t>=u,R=!e[c]||!`'"`.includes(e[c]);return!!(m&&n&&g&&f&&D&&R)}if(i&&e[u]===b&&e[t]===b)return!1;if(e[t]==="/"||e[t]===">"||e[t]==="<"){let m=e[l]===e[u]&&s===u&&!e.slice(l+1,u).includes(e[l]),n=$.get("matchedPairs")<2,g=P(e,t),f=(!g||!r.has(g))&&(!(t>u&&$.get("'")&&$.get('"')&&$.get("matchedPairs")>1)||"/>".includes(e[c])),D=d<3||+$.get('"')+ +$.get("'")-$.get("matchedPairs")*2!==2,R=!h||h&&!(E!==void 0&&Array.from(e.slice(l+1,E).trim()).every(k=>p(k))&&r.has(e.slice(l+1,E).trim())),V=!c&&d%2===0,A=e[l-2]&&e[l-1]==="="&&p(e[l-2]),C=!M(e,t+1,"<",["='",'="']);return m||(n||f)&&D&&(R||V||A||C)}if(e[t]==="="&&j(e,t,["'",'"'],{trimBeforeMatching:!0,trimCharsBeforeMatching:["="]}))return!0}else{let m;if(e[t-1]?.trim()&&e[t-1]!=="=")m=t-1;else for(let n=t;n--;)if(e[n].trim()&&e[n]!=="="){m=n;break}if(e[t]==="="&&j(e,t,["'",'"'],{cb:n=>!"/>".includes(n),trimBeforeMatching:!0,trimCharsBeforeMatching:["="]})&&p(e[m])&&!e.slice(l+1).startsWith("http")&&!e.slice(l+1,t).includes("/")&&!e.endsWith("src=",l)&&!e.endsWith("href=",l))return!1;if(t===u&&L(e,t+1))return!0;if(t<u&&`'"`.includes(e[t])&&a&&e[Y(e,l)]&&e[Y(e,l)]!=="="&&E===l&&r.has(a))return!1;if(t===u&&`'"`.includes(e[t])&&(e[B]==="'"||e[B]==='"')&&a&&S&&d%2===0&&S.endsWith(":")||t===u&&`'"`.includes(e[t])&&e.slice(l,u).includes(":")&&(e[c]===">"||e[c]==="/"&&e[v(e,c)]===">"))return!0}if(`'"`.includes(e[t])&&t>u)return!(!F||!a||!r.has(a));`'"`.includes(e[t])&&(s=t),o&&!p(e[t])&&(o=null)}return!1}export{ne as isAttrClosing,$e as version};