1let isPackingList = false; 2let isReviewProduct = false; 3let isBlogPost = false; 4let hasNumberedBlogProducts = false; 5let divs = []; 6 7if ( document.body.classList.contains( 'single-packing-list' ) ) { 8 divs = document.querySelectorAll( '.packing-list-intro p:not(:empty), .packing-list-gear-section, .packing-list-overall p:not(:empty)' ); 9 isPackingList = true; 10} 11 12if ( document.body.classList.contains( 'single-review-product' ) ) { 13 divs = document.querySelectorAll( '.full-review-body p:not(:empty)' ); 14 isReviewProduct = true; 15} 16 17if ( document.body.classList.contains( 'single-post' ) ) { 18 divs = document.querySelectorAll( '.entry-content > p:not(:empty), .entry-content > .blog-review-product-item, .entry-content > .multi_product_list_content > p:not(:empty)' ); 19 isBlogPost = true; 20 21 const numberedProducts = document.querySelectorAll( '.entry-content > .blog-review-product-item .blog-review-product-item-headline' ); 22 hasNumberedBlogProducts = Array.from( numberedProducts ).some( ( headline ) => /^\s*\d+\./.test( ( headline.textContent || '' ).trim() ) ); 23} 24 25function getNumberedBlogProductItems() { 26 const productItems = document.querySelectorAll( '.entry-content > .blog-review-product-item' ); 27 28 return Array.from( productItems ).filter( ( productItem ) => { 29 const headline = productItem.querySelector( '.blog-review-product-item-headline' ); 30 31 if ( ! headline ) { 32 return false; 33 } 34 35 return /^\s*\d+\./.test( ( headline.textContent || '' ).trim() ); 36 } ); 37} 38 39function insertAfterDesktop() { 40 if ( false == isPackingList && false == isBlogPost && false == isReviewProduct ) { 41 return; 42 } 43 44 if ( isBlogPost && hasNumberedBlogProducts ) { 45 const numberedProductItems = getNumberedBlogProductItems(); 46 47 numberedProductItems.forEach( ( productItem ) => { 48 const div = createDiv(); 49 productItem.before( div ); 50 } ); 51 52 return; 53 } 54 55 let current, next, step; 56 57 if ( isPackingList ) { 58 current = 1; 59 next = 3; 60 step = 5; 61 } 62 63 if ( isReviewProduct ) { 64 current = 1; 65 next = 4; 66 step = 4; 67 } 68 69 if ( isBlogPost ) { 70 current = 1; 71 next = 7; 72 step = 7; 73 } 74 75 for (let count = 1; count <= divs.length; count++) { 76 if ( next == count ) { 77 const div = createDiv(); 78 divs[ ( count - 1 ) ].after( div ); 79 next = current + step; 80 } 81 82 current++; 83 } 84} 85 86function insertAfterMobile() { 87 if ( false == isPackingList && false == isBlogPost && false == isReviewProduct ) { 88 return; 89 } 90 91 if ( isBlogPost && hasNumberedBlogProducts ) { 92 const numberedProductItems = getNumberedBlogProductItems(); 93 94 numberedProductItems.forEach( ( productItem ) => { 95 const div = createDiv(); 96 productItem.before( div ); 97 } ); 98 99 return; 100 } 101 102 let current, next, step, skip; 103 104 if ( isPackingList ) { 105 current = 1; 106 next = 3; 107 step = 5; 108 skip = 8; 109 } 110 111 if ( isReviewProduct ) { 112 current = 1; 113 next = 5; 114 step = 5; 115 skip = 5; 116 } 117 118 if ( isBlogPost ) { 119 current = 1; 120 next = 5; 121 step = 5; 122 skip = 10; 123 } 124 125 for (let count = 1; count <= divs.length; count++) { 126 if ( next == count ) { 127 if ( count == skip ) { 128 const div = createMobileScroller(); 129 divs[ ( count - 1 ) ].after( div ); 130 } else { 131 const div = createDiv(); 132 divs[ ( count - 1 ) ].after( div ); 133 } 134 next = current + step; 135 } 136 137 current++; 138 } 139} 140 141function createDiv() { 142 const div = document.createElement('div'); 143 const uniqid = generateUniqId(); 144 145 if ( ! isMobile ) { 146 if ( isPackingList || isReviewProduct ) { 147 div.classList.add( 'packh-content-leaderboard'); 148 149 const divChild = document.createElement('div'); 150 divChild.id = 'desktop-content-' + uniqid; 151 divChild.className = 'asc-load-ad scroll-track-ad'; 152 divChild.setAttribute('ot-name', 'ph_dt_content'); 153 divChild.setAttribute( 'style', 'text-align:center;' ); 154 155 div.appendChild( divChild ); 156 } 157 if ( isBlogPost ) { 158 div.classList.add( 'packh-mid-leaderboard'); 159 160 const divChild = document.createElement('div'); 161 divChild.id = 'desktop-mid-leaderboard-' + uniqid; 162 divChild.className = 'asc-load-ad scroll-track-ad'; 163 divChild.setAttribute('ot-name', 'ph_dt_billboard_mid'); 164 divChild.setAttribute( 'style', 'text-align:center;' ); 165 166 div.appendChild( divChild ); 167 } 168 } else { 169 div.classList.add( 'packh-mobile-mpu'); 170 171 const divChild = document.createElement('div'); 172 divChild.id = 'mobile-mpu-' + uniqid; 173 divChild.className = 'asc-load-ad scroll-track-ad'; 174 divChild.setAttribute('ot-name', 'ph_mob_mpu'); 175 divChild.setAttribute( 'style', 'text-align:center;' ); 176 177 div.appendChild( divChild ); 178 } 179 180 return div; 181} 182 183function createMobileScroller(){ 184 const div = document.createElement('div'); 185 div.id = 'ph-mobile-scroller'; 186 div.innerHTML = '<div id="interscroller-wrapper" class="interscroller-wrapper scroll-track-ad" data-type="scroll-track-ad"><div id="interscroller-bg-wrapper" class="interscroller-bg-wrapper"><div id="interscroller-bg" class="interscroller-bg"><div id="inscroll-banner"><div id="banner-core"><div id="iscroll-clip"><div id="mobile-interscroller" style="text-align: center;" data-unit="ph_mob_scroller" data-size="MobScroller" class="lazyload-ads" ot-name="ph_mob_scroller"></div></div></div></div></div></div></div>'; 187 return div; 188} 189 190function generateUniqId(prefix = "", random = false) { 191 const sec = Date.now() * 1000 + Math.random() * 1000; 192 const id = sec.toString(16).replace(/\./g, "").padEnd(14, "0"); 193 194 return `${prefix}${id}${random ? `.${Math.trunc(Math.random() * 100000000)}`:""}`; 195}; 196 197if ( ! isMobile ) { 198 insertAfterDesktop(); 199} else { 200 insertAfterMobile(); 201}
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.