@linkitbe/sdk 1.0.8 → 1.0.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -22,7 +22,7 @@
22
22
  feedObserverRootSelector: null,
23
23
  // true = перед POST integration-viewable запросить GET /v1/events/integration-viewable-token (нужен секрет на markup-api).
24
24
  fetchImpressionTokenForViewable: true,
25
- sdkVersion: '1.0.8',
25
+ sdkVersion: '1.0.10',
26
26
  styles: {
27
27
  link_color: '#e2187b',
28
28
  link_weight: '700',
@@ -300,6 +300,14 @@
300
300
  preview.style.top = Math.max(margin, top) + 'px';
301
301
  }
302
302
 
303
+ function buildPreviewLabelingEl(integration) {
304
+ const erid = integration && integration.erid != null ? String(integration.erid).trim() : '';
305
+ const label = document.createElement('div');
306
+ label.style.cssText = 'font-size:10px;line-height:1.35;color:#aaa;margin-bottom:6px;font-weight:400;';
307
+ label.textContent = erid ? `#реклама · erid: ${erid}` : '#реклама';
308
+ return label;
309
+ }
310
+
303
311
  function showPreview(preview, integration, x, y, styles_config) {
304
312
  if (!integration.preview || !integration.preview.img) {
305
313
  preview.style.display = 'none';
@@ -308,6 +316,8 @@
308
316
 
309
317
  preview.replaceChildren();
310
318
 
319
+ preview.appendChild(buildPreviewLabelingEl(integration));
320
+
311
321
  const image = document.createElement('img');
312
322
  image.src = String(integration.preview.img);
313
323
  image.style.cssText = 'width:100%;border-radius:8px;display:block;';
@@ -332,6 +342,26 @@
332
342
  positionMarkupPreview(preview, x, y);
333
343
  }
334
344
 
345
+ function hidePreview(preview) {
346
+ if (preview) {
347
+ preview.style.display = 'none';
348
+ }
349
+ }
350
+
351
+ function attachPreviewDismissHandlers(preview) {
352
+ if (!preview || preview.dataset.lbDismissBound === '1') {
353
+ return;
354
+ }
355
+ preview.dataset.lbDismissBound = '1';
356
+
357
+ const dismiss = () => hidePreview(preview);
358
+
359
+ document.addEventListener('visibilitychange', dismiss);
360
+ window.addEventListener('blur', dismiss);
361
+ window.addEventListener('pagehide', dismiss);
362
+ window.addEventListener('pageshow', dismiss);
363
+ }
364
+
335
365
 
336
366
  // ============================================================
337
367
  // 5. KEYWORD: plain, матчи, Range
@@ -657,6 +687,61 @@
657
687
  }
658
688
 
659
689
  const MINI_OFFER_PLACEHOLDER = '{anchor_text}';
690
+ const MOBILE_LAYOUT_MAX_WIDTH = 768;
691
+ const MOBILE_MIN_SIDE_INSET_PX = 8;
692
+ const MOBILE_FALLBACK_SIDE_PADDING_PX = 16;
693
+
694
+ function isMobileLayout() {
695
+ return window.matchMedia(`(max-width: ${MOBILE_LAYOUT_MAX_WIDTH}px)`).matches;
696
+ }
697
+
698
+ function getViewportSideInset(el) {
699
+ const rect = el.getBoundingClientRect();
700
+ return {
701
+ left: rect.left,
702
+ right: window.innerWidth - rect.right,
703
+ };
704
+ }
705
+
706
+ function findReferencePlainBlock(contentBlock, excludeEl) {
707
+ const sel = config.plainBlockSelector || 'p, blockquote, h1, h2, h3, h4, h5, h6';
708
+ const blocks = contentBlock.querySelectorAll(sel);
709
+ for (let i = 0; i < blocks.length; i++) {
710
+ const el = blocks[i];
711
+ if (el === excludeEl || el.classList.contains('__lb_mini_offer')) continue;
712
+ if (!(el.textContent || '').trim()) continue;
713
+ return el;
714
+ }
715
+ return null;
716
+ }
717
+
718
+ function applyMobileSideInsetIfNeeded(outro, contentBlock) {
719
+ if (!isMobileLayout()) return;
720
+
721
+ const currentInset = getViewportSideInset(outro);
722
+ if (currentInset.left >= MOBILE_MIN_SIDE_INSET_PX && currentInset.right >= MOBILE_MIN_SIDE_INSET_PX) {
723
+ return;
724
+ }
725
+
726
+ const ref = findReferencePlainBlock(contentBlock, outro);
727
+ const refInset = ref ? getViewportSideInset(ref) : null;
728
+ const targetLeft = refInset && refInset.left >= MOBILE_MIN_SIDE_INSET_PX
729
+ ? refInset.left
730
+ : MOBILE_FALLBACK_SIDE_PADDING_PX;
731
+ const targetRight = refInset && refInset.right >= MOBILE_MIN_SIDE_INSET_PX
732
+ ? refInset.right
733
+ : MOBILE_FALLBACK_SIDE_PADDING_PX;
734
+
735
+ const padLeft = currentInset.left < MOBILE_MIN_SIDE_INSET_PX
736
+ ? Math.max(0, Math.round(targetLeft - currentInset.left))
737
+ : 0;
738
+ const padRight = currentInset.right < MOBILE_MIN_SIDE_INSET_PX
739
+ ? Math.max(0, Math.round(targetRight - currentInset.right))
740
+ : 0;
741
+
742
+ if (padLeft > 0) outro.style.paddingLeft = `${padLeft}px`;
743
+ if (padRight > 0) outro.style.paddingRight = `${padRight}px`;
744
+ }
660
745
 
661
746
  function applyMiniOffer(contentBlock, integration, linkStyle, labelingTemplate, pageConfig) {
662
747
  if (!contentBlock) {
@@ -696,6 +781,7 @@
696
781
  }
697
782
 
698
783
  contentBlock.appendChild(outro);
784
+ applyMobileSideInsetIfNeeded(outro, contentBlock);
699
785
  return true;
700
786
  }
701
787
 
@@ -747,6 +833,8 @@
747
833
  });
748
834
 
749
835
  if (preview) {
836
+ attachPreviewDismissHandlers(preview);
837
+
750
838
  contentBlock.querySelectorAll('.__lb_link').forEach((linkEl) => {
751
839
  let integration;
752
840
  try {
@@ -758,16 +846,26 @@
758
846
  if (!integration.preview || !integration.preview.img) {
759
847
  return;
760
848
  }
849
+ const dismissPreview = () => hidePreview(preview);
850
+
761
851
  linkEl.addEventListener('mouseenter', (e) => {
852
+ if (document.visibilityState !== 'visible') {
853
+ return;
854
+ }
762
855
  showPreview(preview, integration, e.clientX, e.clientY, style_config);
763
856
  if (linkEl.dataset.lbPreviewSent === '1' || !articleId) return;
764
857
  linkEl.dataset.lbPreviewSent = '1';
765
858
  emitSdkEvent('preview_viewed', '/v1/events/preview-viewed', articleId, integration);
766
859
  });
767
860
  linkEl.addEventListener('mousemove', (e) => {
861
+ if (preview.style.display === 'none') {
862
+ return;
863
+ }
768
864
  positionMarkupPreview(preview, e.clientX, e.clientY);
769
865
  });
770
- linkEl.addEventListener('mouseleave', () => { preview.style.display = 'none'; });
866
+ linkEl.addEventListener('mouseleave', dismissPreview);
867
+ linkEl.addEventListener('click', dismissPreview);
868
+ linkEl.addEventListener('touchstart', dismissPreview, { passive: true });
771
869
  });
772
870
  }
773
871
 
@@ -1 +1 @@
1
- !function(){const e=Object.assign({domain:window.location.hostname,bootOnLoad:!0,contentSelector:null,showPreview:!0,plainBlockJoiner:"\n",plainBlockSelector:"p, blockquote, h1, h2, h3, h4, h5, h6",allowedFormats:["keyword","mini-offer"],apiBaseUrl:"https://api.linkitbe.com",partnerApiKey:null,articleIdResolver:null,enableFeedAutoProcess:!1,feedObserverRootSelector:null,fetchImpressionTokenForViewable:!0,sdkVersion:"1.0.8",styles:{link_color:"#e2187b",link_weight:"700",link_decoration:"underline"}},window.LinkItBeConfig||{});function n(n){if("function"==typeof e.articleIdResolver)try{const t=e.articleIdResolver(n),o=null!=t?String(t).trim():"";if(o)return o}catch(e){console.warn("[LinkItBe] articleIdResolver failed",e)}return null}function t(){const e="__lb_session_id";try{const n=window.localStorage.getItem(e);if(n&&n.trim())return n.trim();const t=window.crypto&&window.crypto.randomUUID?window.crypto.randomUUID():`${Date.now()}-${Math.random().toString(16).slice(2)}`;return window.localStorage.setItem(e,t),t}catch(e){return`${Date.now()}-${Math.random().toString(16).slice(2)}`}}function o(e){if(!Array.isArray(e))return null;for(const n of e){const e=n&&n.link?String(n.link):"";if(e)try{const n=new URL(e,window.location.origin).searchParams.get("processing_id"),t=Number(n);if(Number.isFinite(t)&&t>0)return t}catch(e){}}return null}async function r(n,r,i,l,s){const a=o([l]);if(!a)return;const c=e.partnerApiKey?String(e.partnerApiKey).trim():"";if(!c)return;const d=Object.assign({event_id:window.crypto&&window.crypto.randomUUID?window.crypto.randomUUID():`${Date.now()}-${Math.random().toString(16).slice(2)}`,event_type:n,event_time:(new Date).toISOString(),article_id:i,domain:e.domain,processing_id:a,placement_link:window.location.href,integration_type:l&&null!=l.type?l.type:null,sdk_version:String(e.sdkVersion||""),session_id:t(),referrer:document.referrer||null},s||{});if("integration_viewable"===n&&e.fetchImpressionTokenForViewable){const n=await async function(n,t){const o=e.partnerApiKey?String(e.partnerApiKey).trim():"";if(!o||!t)return null;try{const r=String(e.apiBaseUrl||"https://api.linkitbe.com").replace(/\/$/,""),i=new URL(r+"/v1/events/integration-viewable-token");i.searchParams.set("article_id",n),i.searchParams.set("domain",String(e.domain||"")),i.searchParams.set("processing_id",String(t));const l=await fetch(i.toString(),{method:"GET",headers:{Accept:"application/json","X-Partner-Api-Key":o},credentials:"omit"});if(!l.ok)return null;const s=await l.json();return s&&s.impression_token?String(s.impression_token):null}catch(e){return console.warn("[LinkItBe] impression token fetch failed",e),null}}(i,a);n&&(d.impression_token=n)}try{const n=String(e.apiBaseUrl||"https://api.linkitbe.com").replace(/\/$/,"");await fetch(`${n}${r}`,{method:"POST",headers:{Accept:"application/json","Content-Type":"application/json","X-Partner-Api-Key":c},body:JSON.stringify(d),keepalive:!0,credentials:"omit"})}catch(e){console.warn("[LinkItBe] failed to send "+n,e)}}async function i(e,n,t){if(t<=0)return;const i=function(e){if(!Array.isArray(e))return null;for(let n=0;n<e.length;n++){const t=e[n];if(t&&o([t]))return t}return null}(n);i&&await r("view_rendered","/v1/events/view-rendered",e,i,{integrations_count:t})}function l(n){const t=e.allowedFormats;return null!=t&&Array.isArray(t)?n.filter(e=>t.includes(e.type)):n}function s(e,n,t){const o=12,r=e.offsetHeight||0,i=e.offsetWidth||0;let l=n+16,s=t-r+60;const a=window.innerWidth-i-o;l=Math.min(Math.max(l,o),Math.max(o,a));s+r>window.innerHeight-o&&(s=t-r-o),e.style.left=l+"px",e.style.top=Math.max(o,s)+"px"}function a(e){const n=[],t=document.createTreeWalker(e,NodeFilter.SHOW_TEXT,{acceptNode:e=>function(e){const n=e.nodeType===Node.TEXT_NODE?e.parentElement:e;return!!(n&&n.closest&&n.closest("a.__lb_link"))}(e)?NodeFilter.FILTER_REJECT:NodeFilter.FILTER_ACCEPT});let o;for(;o=t.nextNode();)n.push(o);return n}function c(e,n){if(!n)return[];const t=new RegExp(String(n).replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),"gi");const o=[];let r;for(;null!==(r=t.exec(e));)o.push({start:r.index,end:r.index+r[0].length}),0===r[0].length&&t.lastIndex===r.index&&t.lastIndex++;return o}function d(e){if(null==e)return null;try{const n=new URL(String(e),window.location.origin);return"http:"!==n.protocol&&"https:"!==n.protocol?null:n.toString()}catch(e){return null}}function u(e,n){const t=e&&null!=e.erid?String(e.erid).trim():"",o=d(e&&e.advertiser_info_url);if(o)return function(e,n){const t=null!=n?String(n).trim():"";if(!t||!e)return e;try{const n=new URL(String(e),window.location.origin);return n.searchParams.set("erid",t),n.toString()}catch(n){return e}}(o,t);const r=n&&n.advertiser_info_base_url,i=e&&null!=e.advertiser?String(e.advertiser).trim():"";if(!r||!i)return null;try{const e=new URL(String(r),window.location.origin);return e.searchParams.append("items[]",i),t&&e.searchParams.set("erid",t),e.toString()}catch(e){return null}}function p(e,n,t){const o=e&&"object"==typeof e?e:{},r=o.marker_type||"plain_text",i=o.position||"before_phrase",l=null!=o.marker_text?String(o.marker_text).trim():"",s="font-size:11px;color:#999;display:block;margin-bottom:4px;";if("marker_link"===r){const e=l||"#реклама",o=function(e,n,t,o){const r=u(e,o);if(!r)return console.warn("[LinkItBe] advertiser info url is missing for marker",e&&e.advertiser),null;const i=document.createElement("a");return i.href=r,i.target="_blank",i.rel="noopener noreferrer sponsored nofollow",i.className="__lb_link __lb_advertiser_info_link",i.style.cssText=t.replace(/\s+/g," ").trim(),i.textContent=n,i}(n,e,"font-size:11px;color:#999;font-weight:400;text-decoration:underline;cursor:pointer;",t);if(o){const e=document.createElement("span");return e.style.cssText=s.replace("margin-bottom:4px;",""),e.appendChild(o),{node:e,position:i}}console.warn("[LinkItBe] marker_link fallback to plain text:",e);const r=document.createElement("span");return r.style.cssText=s,r.textContent=e,{node:r,position:i}}"plain_text"!==r&&console.warn("[LinkItBe] unsupported marker_type, fallback to plain_text:",r);const a=document.createElement("span");return a.style.cssText=s,a.textContent=function(e){const n=String(e||"#реклама").trim();return n?n.endsWith(":")?n:n.replace(/:+$/,"")+":":"#реклама"}(l||"#реклама"),{node:a,position:i}}function f(e,n,t){const o=d(e.link);if(!o)return null;const r=document.createElement("a");return r.href=o,r.target="_blank",r.rel="noopener noreferrer sponsored nofollow",r.className="__lb_link",r.setAttribute("data-lb-integration",encodeURIComponent(JSON.stringify(e))),r.style.cssText=t.replace(/\s+/g," ").trim(),r.textContent=n,r}function m(n,t){const{plain:o,spans:r}=function(n){const t=null!=e.plainBlockJoiner?e.plainBlockJoiner:"\n",o=e.plainBlockSelector||"p, blockquote, h1, h2, h3, h4, h5, h6",r=n.querySelectorAll(o),i=[];let l="";return r.forEach((e,n)=>{n>0&&(l+=t);const o=a(e);for(const e of o){const n=e.textContent;if(!n.length)continue;const t=l.length;l+=n,i.push({g0:t,g1:l.length,node:e})}}),{plain:l,spans:i}}(n),i=function(e,n){if(!e.length)return null;if(1===e.length)return e[0];const t=n||{},o=t.match_index;if(null!=o&&Number.isFinite(Number(o))){const n=Number(o);if(n>=0&&n<e.length)return e[n];console.warn("[LinkItBe] match_index out of range:",o,"n=",e.length)}const r=t.offset_start,i=t.offset_end;if(null!=r&&Number.isFinite(Number(r))){const n=Number(r),t=null!=i&&Number.isFinite(Number(i))?Number(i):null;let o=e[0],l=1/0;for(const r of e){const e=1e9*Math.abs(r.start-n)+(null!=t?Math.abs(r.end-t):0);e<l&&(l=e,o=r)}return o}return console.warn("[LinkItBe] ambiguous matches, skipping (no match_index / offset_start):",e.length),null}(c(o,t.keyword),t.position);if(!i)return null;const l=o.slice(i.start,i.end);return{plain:o,spans:r,span:i,linkText:l}}function w(e,n,t){const o=m(e,n);if(!o)return console.warn("[LinkItBe] no span for keyword:",n.keyword),!1;const{plain:r,spans:i,span:l,linkText:s}=o,a=function(e,n,t){if(e<0||e>=t||!n.length)return null;const o=n.find(n=>e>=n.g0&&e<n.g1);return o?{node:o.node,offset:e-o.g0}:null}(l.start,i,r.length),c=function(e,n,t){if(!n.length)return null;if(e<=0)return{node:n[0].node,offset:0};if(e>=t){const e=n[n.length-1];return{node:e.node,offset:e.node.textContent.length}}for(let t=0;t<n.length;t++){const o=n[t];if(e>o.g0&&e<=o.g1)return{node:o.node,offset:e-o.g0};if(e===o.g0)return{node:o.node,offset:0}}for(let t=0;t<n.length;t++)if(e<n[t].g0)return{node:n[t].node,offset:0};return null}(l.end,i,r.length);if(!a||!c)return console.warn("[LinkItBe] could not map span to DOM"),!1;const d=r.slice(l.start,l.end);if(d.toLowerCase()!==s.toLowerCase())return console.warn("[LinkItBe] plain slice mismatch"),!1;const u=document.createRange();u.setStart(a.node,a.offset),u.setEnd(c.node,c.offset);const p=f(n,d,t);return p?(function(e,n){try{e.surroundContents(n)}catch(t){const o=e.extractContents();for(;o.firstChild;)n.appendChild(o.firstChild);e.insertNode(n)}}(u,p),!0):(console.warn("[LinkItBe] invalid integration link:",n.link),!1)}const h="{anchor_text}";function g(n,t,o,i,a,c){if(!o){console.warn("[LinkItBe] Content block not provided");return{appliedCount:0,integrations:l(t)}}const d=e.showPreview?function(){const e=document.createElement("div");return e.id="__lb_preview",e.style.cssText="\n position: fixed;\n display: none;\n background: white;\n border-radius: 12px;\n box-shadow: 0 4px 20px rgba(0,0,0,0.15);\n padding: 12px;\n z-index: 99999;\n width: 180px;\n font-family: Manrope, sans-serif;\n pointer-events: none;\n ",document.body.appendChild(e),e}():null,u=`\n color:${i.link_color};\n font-weight:${i.link_weight};\n text-decoration:${i.link_decoration};\n cursor:pointer;\n `,g=l(t);let b=0,_=g.filter(e=>"keyword"===e.type);for(;_.length;){const e=[];for(const n of _){const t=m(o,n);t&&e.push({integ:n,spanStart:t.span.start})}if(!e.length){_.forEach(e=>console.warn("[LinkItBe] unresolved keyword:",e.keyword));break}e.sort((e,n)=>n.spanStart-e.spanStart);const{integ:n}=e[0];w(o,n,u)&&(b+=1),_=_.filter(e=>e!==n)}return g.filter(e=>"mini-offer"===e.type).forEach(e=>{!function(e,n,t,o,r){if(!e)return console.warn("[LinkItBe] mini-offer: no content block"),!1;const i=document.createElement("p");i.className="__lb_mini_offer",i.style.cssText="margin-top:16px;font-size:15px;font-family:Manrope, sans-serif;color:#343b4c;";const l=p(o,n,r),s=document.createElement("span"),a=null!=n.text?String(n.text):"",c=null!=n.anchor_text?String(n.anchor_text):"",d=a.indexOf(h),u=d>=0?a.slice(0,d):a,m=d>=0?a.slice(d+13):"";u&&s.appendChild(document.createTextNode(u));const w=f(n,c,t);return w?(s.appendChild(w),m&&s.appendChild(document.createTextNode(m)),l&&"before_phrase"===l.position&&i.appendChild(l.node),i.appendChild(s),l&&"after_phrase"===l.position&&(i.appendChild(document.createElement("br")),i.appendChild(l.node)),e.appendChild(i),!0):(console.warn("[LinkItBe] mini-offer invalid integration link:",n.link),!1)}(o,e,u,a,c)?console.warn("[LinkItBe] mini-offer failed"):b+=1}),d&&o.querySelectorAll(".__lb_link").forEach(e=>{let t;try{t=JSON.parse(decodeURIComponent(e.dataset.lbIntegration||""))}catch(e){return void console.warn("[LinkItBe] invalid integration payload for preview",e)}t.preview&&t.preview.img&&(e.addEventListener("mouseenter",o=>{!function(e,n,t,o,r){if(!n.preview||!n.preview.img)return void(e.style.display="none");e.replaceChildren();const i=document.createElement("img");i.src=String(n.preview.img),i.style.cssText="width:100%;border-radius:8px;display:block;",e.appendChild(i);const l=document.createElement("div");l.style.cssText="margin-top:8px;font-size:13px;color:#343b4c;font-weight:600;",l.textContent=n.preview.title?String(n.preview.title):"",e.appendChild(l);const a=document.createElement("div");a.style.cssText="font-size:12px;color:#777;margin-top:2px;",a.textContent=n.preview.price?String(n.preview.price):"",e.appendChild(a);const c=document.createElement("div");c.style.cssText=`font-size:12px;color:${r.link_color};margin-top:2px;`,c.textContent=n.preview.cta?String(n.preview.cta):"",e.appendChild(c),e.style.display="block",s(e,t,o)}(d,t,o.clientX,o.clientY,i),"1"!==e.dataset.lbPreviewSent&&n&&(e.dataset.lbPreviewSent="1",r("preview_viewed","/v1/events/preview-viewed",n,t))}),e.addEventListener("mousemove",e=>{s(d,e.clientX,e.clientY)}),e.addEventListener("mouseleave",()=>{d.style.display="none"}))}),function(e,n){if(!e)return;const t=e=>{const n=e._lbViewDwellTimer;n&&(clearTimeout(n),e._lbViewDwellTimer=null)},o=new IntersectionObserver(n=>{for(let i=0;i<n.length;i++){const l=n[i],s=l.target;"1"!==s.dataset.lbViewableSent&&(!l.isIntersecting||l.intersectionRatio<.5?(t(s),s._lbViewVisibleSince=null,s._lbViewLastIr=null):(s._lbViewLastIr=String(Math.min(1,Math.max(0,l.intersectionRatio))),s._lbViewVisibleSince||(s._lbViewVisibleSince=Date.now()),t(s),s._lbViewDwellTimer=setTimeout(()=>{if(s._lbViewDwellTimer=null,"1"===s.dataset.lbViewableSent)return;if("visible"!==document.visibilityState)return;let n;try{n=JSON.parse(decodeURIComponent(s.dataset.lbIntegration||""))}catch(e){return void o.unobserve(s)}s.dataset.lbViewableSent="1";const t=s._lbViewVisibleSince||Date.now(),i=Math.max(0,Date.now()-t),l=parseFloat(s._lbViewLastIr||"0.5");r("integration_viewable","/v1/events/integration-viewable",e,n,{tab_visible:"visible"===document.visibilityState,dwell_ms:Math.max(1e3,i),intersection_ratio:l,viewability_rule_version:"elitesdk-1"}),o.unobserve(s)},1e3)))}},{threshold:[.5]});n.querySelectorAll(".__lb_link").forEach(e=>o.observe(e))}(n,o),{appliedCount:b,integrations:g}}async function b(n,t){if(!function(e,n){return e?!!n||(console.warn("[LinkItBe] Content block not found for article:",e),!1):(console.warn("[LinkItBe] Article ID not found"),!1)}(n,t))return;if("1"===t.dataset.lbProcessed)return;const o=await async function(n){const t=`${String(e.apiBaseUrl||"https://api.linkitbe.com").replace(/\/$/,"")}/v1/markup?article_id=${encodeURIComponent(n)}&domain=${encodeURIComponent(e.domain)}`,o={Accept:"application/json"},r=e.partnerApiKey?String(e.partnerApiKey).trim():"";r&&(o["X-Partner-Api-Key"]=r);const i=await fetch(t,{method:"GET",headers:o,credentials:"omit"});return i.ok?await i.json():null}(n);o&&await async function(e,n,t){if("1"===n.dataset.lbProcessed)return;n.dataset.lbProcessed="1";const o=Array.isArray(t.integrations)?t.integrations:[],r=t.config&&"object"==typeof t.config?t.config:{},l=g(e,o,n,r.style||{},r.labeling_template||null,r);await i(e,l.integrations,l.appliedCount)}(n,t,o)}function _(t){if(t.nodeType!==Node.ELEMENT_NODE)return;const o=t.querySelector(e.contentSelector);if(!o)return;b(n(o),o)}function k(e){if(!e)return void console.warn("[LinkItBe] feedRoot not provided for auto markup");new MutationObserver(e=>{for(const n of e)for(let e=0;e<n.addedNodes.length;e++)_(n.addedNodes[e])}).observe(e,{childList:!0,subtree:!0})}async function y(){const t=document.querySelector(e.contentSelector),o=n(t);if(await b(o,t),!0!==e.enableFeedAutoProcess)return;const r=document.querySelector(e.feedObserverRootSelector);r?k(r):console.warn("[LinkItBe] feedObserverRootSelector not found:",e.feedObserverRootSelector)}"loading"===document.readyState?document.addEventListener("DOMContentLoaded",y):!0===e.bootOnLoad&&y(),window.LinkItBe=Object.assign({},window.LinkItBe||{},{initArticle:b,startFeedAutoMarkup:k})}();
1
+ !function(){const e=Object.assign({domain:window.location.hostname,bootOnLoad:!0,contentSelector:null,showPreview:!0,plainBlockJoiner:"\n",plainBlockSelector:"p, blockquote, h1, h2, h3, h4, h5, h6",allowedFormats:["keyword","mini-offer"],apiBaseUrl:"https://api.linkitbe.com",partnerApiKey:null,articleIdResolver:null,enableFeedAutoProcess:!1,feedObserverRootSelector:null,fetchImpressionTokenForViewable:!0,sdkVersion:"1.0.10",styles:{link_color:"#e2187b",link_weight:"700",link_decoration:"underline"}},window.LinkItBeConfig||{});function t(t){if("function"==typeof e.articleIdResolver)try{const n=e.articleIdResolver(t),i=null!=n?String(n).trim():"";if(i)return i}catch(e){console.warn("[LinkItBe] articleIdResolver failed",e)}return null}function n(){const e="__lb_session_id";try{const t=window.localStorage.getItem(e);if(t&&t.trim())return t.trim();const n=window.crypto&&window.crypto.randomUUID?window.crypto.randomUUID():`${Date.now()}-${Math.random().toString(16).slice(2)}`;return window.localStorage.setItem(e,n),n}catch(e){return`${Date.now()}-${Math.random().toString(16).slice(2)}`}}function i(e){if(!Array.isArray(e))return null;for(const t of e){const e=t&&t.link?String(t.link):"";if(e)try{const t=new URL(e,window.location.origin).searchParams.get("processing_id"),n=Number(t);if(Number.isFinite(n)&&n>0)return n}catch(e){}}return null}async function o(t,o,r,l,s){const a=i([l]);if(!a)return;const c=e.partnerApiKey?String(e.partnerApiKey).trim():"";if(!c)return;const d=Object.assign({event_id:window.crypto&&window.crypto.randomUUID?window.crypto.randomUUID():`${Date.now()}-${Math.random().toString(16).slice(2)}`,event_type:t,event_time:(new Date).toISOString(),article_id:r,domain:e.domain,processing_id:a,placement_link:window.location.href,integration_type:l&&null!=l.type?l.type:null,sdk_version:String(e.sdkVersion||""),session_id:n(),referrer:document.referrer||null},s||{});if("integration_viewable"===t&&e.fetchImpressionTokenForViewable){const t=await async function(t,n){const i=e.partnerApiKey?String(e.partnerApiKey).trim():"";if(!i||!n)return null;try{const o=String(e.apiBaseUrl||"https://api.linkitbe.com").replace(/\/$/,""),r=new URL(o+"/v1/events/integration-viewable-token");r.searchParams.set("article_id",t),r.searchParams.set("domain",String(e.domain||"")),r.searchParams.set("processing_id",String(n));const l=await fetch(r.toString(),{method:"GET",headers:{Accept:"application/json","X-Partner-Api-Key":i},credentials:"omit"});if(!l.ok)return null;const s=await l.json();return s&&s.impression_token?String(s.impression_token):null}catch(e){return console.warn("[LinkItBe] impression token fetch failed",e),null}}(r,a);t&&(d.impression_token=t)}try{const t=String(e.apiBaseUrl||"https://api.linkitbe.com").replace(/\/$/,"");await fetch(`${t}${o}`,{method:"POST",headers:{Accept:"application/json","Content-Type":"application/json","X-Partner-Api-Key":c},body:JSON.stringify(d),keepalive:!0,credentials:"omit"})}catch(e){console.warn("[LinkItBe] failed to send "+t,e)}}async function r(e,t,n){if(n<=0)return;const r=function(e){if(!Array.isArray(e))return null;for(let t=0;t<e.length;t++){const n=e[t];if(n&&i([n]))return n}return null}(t);r&&await o("view_rendered","/v1/events/view-rendered",e,r,{integrations_count:n})}function l(t){const n=e.allowedFormats;return null!=n&&Array.isArray(n)?t.filter(e=>n.includes(e.type)):t}function s(e,t,n){const i=12,o=e.offsetHeight||0,r=e.offsetWidth||0;let l=t+16,s=n-o+60;const a=window.innerWidth-r-i;l=Math.min(Math.max(l,i),Math.max(i,a));s+o>window.innerHeight-i&&(s=n-o-i),e.style.left=l+"px",e.style.top=Math.max(i,s)+"px"}function a(e,t,n,i,o){if(!t.preview||!t.preview.img)return void(e.style.display="none");e.replaceChildren(),e.appendChild(function(e){const t=e&&null!=e.erid?String(e.erid).trim():"",n=document.createElement("div");return n.style.cssText="font-size:10px;line-height:1.35;color:#aaa;margin-bottom:6px;font-weight:400;",n.textContent=t?`#реклама · erid: ${t}`:"#реклама",n}(t));const r=document.createElement("img");r.src=String(t.preview.img),r.style.cssText="width:100%;border-radius:8px;display:block;",e.appendChild(r);const l=document.createElement("div");l.style.cssText="margin-top:8px;font-size:13px;color:#343b4c;font-weight:600;",l.textContent=t.preview.title?String(t.preview.title):"",e.appendChild(l);const a=document.createElement("div");a.style.cssText="font-size:12px;color:#777;margin-top:2px;",a.textContent=t.preview.price?String(t.preview.price):"",e.appendChild(a);const c=document.createElement("div");c.style.cssText=`font-size:12px;color:${o.link_color};margin-top:2px;`,c.textContent=t.preview.cta?String(t.preview.cta):"",e.appendChild(c),e.style.display="block",s(e,n,i)}function c(e){e&&(e.style.display="none")}function d(e){const t=[],n=document.createTreeWalker(e,NodeFilter.SHOW_TEXT,{acceptNode:e=>function(e){const t=e.nodeType===Node.TEXT_NODE?e.parentElement:e;return!!(t&&t.closest&&t.closest("a.__lb_link"))}(e)?NodeFilter.FILTER_REJECT:NodeFilter.FILTER_ACCEPT});let i;for(;i=n.nextNode();)t.push(i);return t}function u(e,t){if(!t)return[];const n=new RegExp(String(t).replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),"gi");const i=[];let o;for(;null!==(o=n.exec(e));)i.push({start:o.index,end:o.index+o[0].length}),0===o[0].length&&n.lastIndex===o.index&&n.lastIndex++;return i}function p(e){if(null==e)return null;try{const t=new URL(String(e),window.location.origin);return"http:"!==t.protocol&&"https:"!==t.protocol?null:t.toString()}catch(e){return null}}function f(e,t){const n=e&&null!=e.erid?String(e.erid).trim():"",i=p(e&&e.advertiser_info_url);if(i)return function(e,t){const n=null!=t?String(t).trim():"";if(!n||!e)return e;try{const t=new URL(String(e),window.location.origin);return t.searchParams.set("erid",n),t.toString()}catch(t){return e}}(i,n);const o=t&&t.advertiser_info_base_url,r=e&&null!=e.advertiser?String(e.advertiser).trim():"";if(!o||!r)return null;try{const e=new URL(String(o),window.location.origin);return e.searchParams.append("items[]",r),n&&e.searchParams.set("erid",n),e.toString()}catch(e){return null}}function m(e,t,n){const i=e&&"object"==typeof e?e:{},o=i.marker_type||"plain_text",r=i.position||"before_phrase",l=null!=i.marker_text?String(i.marker_text).trim():"",s="font-size:11px;color:#999;display:block;margin-bottom:4px;";if("marker_link"===o){const e=l||"#реклама",i=function(e,t,n,i){const o=f(e,i);if(!o)return console.warn("[LinkItBe] advertiser info url is missing for marker",e&&e.advertiser),null;const r=document.createElement("a");return r.href=o,r.target="_blank",r.rel="noopener noreferrer sponsored nofollow",r.className="__lb_link __lb_advertiser_info_link",r.style.cssText=n.replace(/\s+/g," ").trim(),r.textContent=t,r}(t,e,"font-size:11px;color:#999;font-weight:400;text-decoration:underline;cursor:pointer;",n);if(i){const e=document.createElement("span");return e.style.cssText=s.replace("margin-bottom:4px;",""),e.appendChild(i),{node:e,position:r}}console.warn("[LinkItBe] marker_link fallback to plain text:",e);const o=document.createElement("span");return o.style.cssText=s,o.textContent=e,{node:o,position:r}}"plain_text"!==o&&console.warn("[LinkItBe] unsupported marker_type, fallback to plain_text:",o);const a=document.createElement("span");return a.style.cssText=s,a.textContent=function(e){const t=String(e||"#реклама").trim();return t?t.endsWith(":")?t:t.replace(/:+$/,"")+":":"#реклама"}(l||"#реклама"),{node:a,position:r}}function h(e,t,n){const i=p(e.link);if(!i)return null;const o=document.createElement("a");return o.href=i,o.target="_blank",o.rel="noopener noreferrer sponsored nofollow",o.className="__lb_link",o.setAttribute("data-lb-integration",encodeURIComponent(JSON.stringify(e))),o.style.cssText=n.replace(/\s+/g," ").trim(),o.textContent=t,o}function w(t,n){const{plain:i,spans:o}=function(t){const n=null!=e.plainBlockJoiner?e.plainBlockJoiner:"\n",i=e.plainBlockSelector||"p, blockquote, h1, h2, h3, h4, h5, h6",o=t.querySelectorAll(i),r=[];let l="";return o.forEach((e,t)=>{t>0&&(l+=n);const i=d(e);for(const e of i){const t=e.textContent;if(!t.length)continue;const n=l.length;l+=t,r.push({g0:n,g1:l.length,node:e})}}),{plain:l,spans:r}}(t),r=function(e,t){if(!e.length)return null;if(1===e.length)return e[0];const n=t||{},i=n.match_index;if(null!=i&&Number.isFinite(Number(i))){const t=Number(i);if(t>=0&&t<e.length)return e[t];console.warn("[LinkItBe] match_index out of range:",i,"n=",e.length)}const o=n.offset_start,r=n.offset_end;if(null!=o&&Number.isFinite(Number(o))){const t=Number(o),n=null!=r&&Number.isFinite(Number(r))?Number(r):null;let i=e[0],l=1/0;for(const o of e){const e=1e9*Math.abs(o.start-t)+(null!=n?Math.abs(o.end-n):0);e<l&&(l=e,i=o)}return i}return console.warn("[LinkItBe] ambiguous matches, skipping (no match_index / offset_start):",e.length),null}(u(i,n.keyword),n.position);if(!r)return null;const l=i.slice(r.start,r.end);return{plain:i,spans:o,span:r,linkText:l}}function g(e,t,n){const i=w(e,t);if(!i)return console.warn("[LinkItBe] no span for keyword:",t.keyword),!1;const{plain:o,spans:r,span:l,linkText:s}=i,a=function(e,t,n){if(e<0||e>=n||!t.length)return null;const i=t.find(t=>e>=t.g0&&e<t.g1);return i?{node:i.node,offset:e-i.g0}:null}(l.start,r,o.length),c=function(e,t,n){if(!t.length)return null;if(e<=0)return{node:t[0].node,offset:0};if(e>=n){const e=t[t.length-1];return{node:e.node,offset:e.node.textContent.length}}for(let n=0;n<t.length;n++){const i=t[n];if(e>i.g0&&e<=i.g1)return{node:i.node,offset:e-i.g0};if(e===i.g0)return{node:i.node,offset:0}}for(let n=0;n<t.length;n++)if(e<t[n].g0)return{node:t[n].node,offset:0};return null}(l.end,r,o.length);if(!a||!c)return console.warn("[LinkItBe] could not map span to DOM"),!1;const d=o.slice(l.start,l.end);if(d.toLowerCase()!==s.toLowerCase())return console.warn("[LinkItBe] plain slice mismatch"),!1;const u=document.createRange();u.setStart(a.node,a.offset),u.setEnd(c.node,c.offset);const p=h(t,d,n);return p?(function(e,t){try{e.surroundContents(t)}catch(n){const i=e.extractContents();for(;i.firstChild;)t.appendChild(i.firstChild);e.insertNode(t)}}(u,p),!0):(console.warn("[LinkItBe] invalid integration link:",t.link),!1)}const b="{anchor_text}";function y(e){const t=e.getBoundingClientRect();return{left:t.left,right:window.innerWidth-t.right}}function _(t,n){if(!window.matchMedia("(max-width: 768px)").matches)return;const i=y(t);if(i.left>=8&&i.right>=8)return;const o=function(t,n){const i=e.plainBlockSelector||"p, blockquote, h1, h2, h3, h4, h5, h6",o=t.querySelectorAll(i);for(let e=0;e<o.length;e++){const t=o[e];if(t!==n&&!t.classList.contains("__lb_mini_offer")&&(t.textContent||"").trim())return t}return null}(n,t),r=o?y(o):null,l=r&&r.left>=8?r.left:16,s=r&&r.right>=8?r.right:16,a=i.left<8?Math.max(0,Math.round(l-i.left)):0,c=i.right<8?Math.max(0,Math.round(s-i.right)):0;a>0&&(t.style.paddingLeft=`${a}px`),c>0&&(t.style.paddingRight=`${c}px`)}function k(t,n,i,r,d,u){if(!i){console.warn("[LinkItBe] Content block not provided");return{appliedCount:0,integrations:l(n)}}const p=e.showPreview?function(){const e=document.createElement("div");return e.id="__lb_preview",e.style.cssText="\n position: fixed;\n display: none;\n background: white;\n border-radius: 12px;\n box-shadow: 0 4px 20px rgba(0,0,0,0.15);\n padding: 12px;\n z-index: 99999;\n width: 180px;\n font-family: Manrope, sans-serif;\n pointer-events: none;\n ",document.body.appendChild(e),e}():null,f=`\n color:${r.link_color};\n font-weight:${r.link_weight};\n text-decoration:${r.link_decoration};\n cursor:pointer;\n `,y=l(n);let k=0,v=y.filter(e=>"keyword"===e.type);for(;v.length;){const e=[];for(const t of v){const n=w(i,t);n&&e.push({integ:t,spanStart:n.span.start})}if(!e.length){v.forEach(e=>console.warn("[LinkItBe] unresolved keyword:",e.keyword));break}e.sort((e,t)=>t.spanStart-e.spanStart);const{integ:t}=e[0];g(i,t,f)&&(k+=1),v=v.filter(e=>e!==t)}return y.filter(e=>"mini-offer"===e.type).forEach(e=>{!function(e,t,n,i,o){if(!e)return console.warn("[LinkItBe] mini-offer: no content block"),!1;const r=document.createElement("p");r.className="__lb_mini_offer",r.style.cssText="margin-top:16px;font-size:15px;font-family:Manrope, sans-serif;color:#343b4c;";const l=m(i,t,o),s=document.createElement("span"),a=null!=t.text?String(t.text):"",c=null!=t.anchor_text?String(t.anchor_text):"",d=a.indexOf(b),u=d>=0?a.slice(0,d):a,p=d>=0?a.slice(d+13):"";u&&s.appendChild(document.createTextNode(u));const f=h(t,c,n);return f?(s.appendChild(f),p&&s.appendChild(document.createTextNode(p)),l&&"before_phrase"===l.position&&r.appendChild(l.node),r.appendChild(s),l&&"after_phrase"===l.position&&(r.appendChild(document.createElement("br")),r.appendChild(l.node)),e.appendChild(r),_(r,e),!0):(console.warn("[LinkItBe] mini-offer invalid integration link:",t.link),!1)}(i,e,f,d,u)?console.warn("[LinkItBe] mini-offer failed"):k+=1}),p&&(!function(e){if(!e||"1"===e.dataset.lbDismissBound)return;e.dataset.lbDismissBound="1";const t=()=>c(e);document.addEventListener("visibilitychange",t),window.addEventListener("blur",t),window.addEventListener("pagehide",t),window.addEventListener("pageshow",t)}(p),i.querySelectorAll(".__lb_link").forEach(e=>{let n;try{n=JSON.parse(decodeURIComponent(e.dataset.lbIntegration||""))}catch(e){return void console.warn("[LinkItBe] invalid integration payload for preview",e)}if(!n.preview||!n.preview.img)return;const i=()=>c(p);e.addEventListener("mouseenter",i=>{"visible"===document.visibilityState&&(a(p,n,i.clientX,i.clientY,r),"1"!==e.dataset.lbPreviewSent&&t&&(e.dataset.lbPreviewSent="1",o("preview_viewed","/v1/events/preview-viewed",t,n)))}),e.addEventListener("mousemove",e=>{"none"!==p.style.display&&s(p,e.clientX,e.clientY)}),e.addEventListener("mouseleave",i),e.addEventListener("click",i),e.addEventListener("touchstart",i,{passive:!0})})),function(e,t){if(!e)return;const n=e=>{const t=e._lbViewDwellTimer;t&&(clearTimeout(t),e._lbViewDwellTimer=null)},i=new IntersectionObserver(t=>{for(let r=0;r<t.length;r++){const l=t[r],s=l.target;"1"!==s.dataset.lbViewableSent&&(!l.isIntersecting||l.intersectionRatio<.5?(n(s),s._lbViewVisibleSince=null,s._lbViewLastIr=null):(s._lbViewLastIr=String(Math.min(1,Math.max(0,l.intersectionRatio))),s._lbViewVisibleSince||(s._lbViewVisibleSince=Date.now()),n(s),s._lbViewDwellTimer=setTimeout(()=>{if(s._lbViewDwellTimer=null,"1"===s.dataset.lbViewableSent)return;if("visible"!==document.visibilityState)return;let t;try{t=JSON.parse(decodeURIComponent(s.dataset.lbIntegration||""))}catch(e){return void i.unobserve(s)}s.dataset.lbViewableSent="1";const n=s._lbViewVisibleSince||Date.now(),r=Math.max(0,Date.now()-n),l=parseFloat(s._lbViewLastIr||"0.5");o("integration_viewable","/v1/events/integration-viewable",e,t,{tab_visible:"visible"===document.visibilityState,dwell_ms:Math.max(1e3,r),intersection_ratio:l,viewability_rule_version:"elitesdk-1"}),i.unobserve(s)},1e3)))}},{threshold:[.5]});t.querySelectorAll(".__lb_link").forEach(e=>i.observe(e))}(t,i),{appliedCount:k,integrations:y}}async function v(t,n){if(!function(e,t){return e?!!t||(console.warn("[LinkItBe] Content block not found for article:",e),!1):(console.warn("[LinkItBe] Article ID not found"),!1)}(t,n))return;if("1"===n.dataset.lbProcessed)return;const i=await async function(t){const n=`${String(e.apiBaseUrl||"https://api.linkitbe.com").replace(/\/$/,"")}/v1/markup?article_id=${encodeURIComponent(t)}&domain=${encodeURIComponent(e.domain)}`,i={Accept:"application/json"},o=e.partnerApiKey?String(e.partnerApiKey).trim():"";o&&(i["X-Partner-Api-Key"]=o);const r=await fetch(n,{method:"GET",headers:i,credentials:"omit"});return r.ok?await r.json():null}(t);i&&await async function(e,t,n){if("1"===t.dataset.lbProcessed)return;t.dataset.lbProcessed="1";const i=Array.isArray(n.integrations)?n.integrations:[],o=n.config&&"object"==typeof n.config?n.config:{},l=k(e,i,t,o.style||{},o.labeling_template||null,o);await r(e,l.integrations,l.appliedCount)}(t,n,i)}function x(n){if(n.nodeType!==Node.ELEMENT_NODE)return;const i=n.querySelector(e.contentSelector);if(!i)return;v(t(i),i)}function S(e){if(!e)return void console.warn("[LinkItBe] feedRoot not provided for auto markup");new MutationObserver(e=>{for(const t of e)for(let e=0;e<t.addedNodes.length;e++)x(t.addedNodes[e])}).observe(e,{childList:!0,subtree:!0})}async function I(){const n=document.querySelector(e.contentSelector),i=t(n);if(await v(i,n),!0!==e.enableFeedAutoProcess)return;const o=document.querySelector(e.feedObserverRootSelector);o?S(o):console.warn("[LinkItBe] feedObserverRootSelector not found:",e.feedObserverRootSelector)}"loading"===document.readyState?document.addEventListener("DOMContentLoaded",I):!0===e.bootOnLoad&&I(),window.LinkItBe=Object.assign({},window.LinkItBe||{},{initArticle:v,startFeedAutoMarkup:S})}();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@linkitbe/sdk",
3
- "version": "1.0.8",
3
+ "version": "1.0.10",
4
4
  "description": "LinkItBe browser SDK",
5
5
  "license": "UNLICENSED",
6
6
  "publishConfig": {