Skip to content

Commit a4f9d32

Browse files
authored
Add files via upload
1 parent b61dd85 commit a4f9d32

2 files changed

Lines changed: 1217 additions & 11 deletions

File tree

sources/instagram.js

Lines changed: 87 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -265,23 +265,48 @@
265265
// Parsing strategy avoids Instagram's obfuscated class names (which rotate).
266266
// We find comment rows by looking for profile-picture <img> elements inside
267267
// a <section>, then walk up to the row container. The username comes from
268-
// the image's alt text ("<name>'s profile picture" — stable semantic HTML),
269-
// and the message is whatever text follows it in the row.
268+
// the visible username text, and the message is whatever text follows it in
269+
// the row.
270270

271271
var LIVE_COMMENT_INPUT_SELECTOR = "footer textarea, footer input, footer [contenteditable='true'], [aria-label='Add a comment…']";
272272
var PROFILE_IMG_SELECTOR = "img[alt*='profile picture'], img[alt*='profile photo']";
273+
var PROFILE_IMG_FALLBACK_SELECTOR = "img[src]";
273274

274275
var COMMENT_PERMALINK_SELECTOR = "a[href*='/c/']";
275276

276277
function isLivePage(){
277278
try {
278279
var path = window.location.pathname || "";
279280
if (path.includes("/live") || path.includes("%2Flive")){ return true; }
280-
if (document.querySelector("svg[aria-label='Viewer count icon']")){ return true; }
281+
if (findViewerCountIcon()){ return true; }
281282
} catch(e){}
282283
return false;
283284
}
284285

286+
function hasViewerCountText(scope){
287+
if (!scope || !scope.querySelectorAll){ return false; }
288+
var spans = scope.querySelectorAll("span");
289+
for (var i = 0; i < spans.length; i++){
290+
var text = (spans[i].textContent || "").trim();
291+
if (/^\d[\d.,]*\s*[KM]?$/i.test(text)){ return true; }
292+
}
293+
return false;
294+
}
295+
296+
function findViewerCountIcon(){
297+
var icon = document.querySelector("svg[aria-label='Viewer count icon']");
298+
if (icon){ return icon; }
299+
var svgs = document.querySelectorAll("header svg[role='img']");
300+
for (var i = 0; i < svgs.length; i++){
301+
var scope = svgs[i].parentElement;
302+
for (var depth = 0; scope && depth < 5; depth++){
303+
if (hasViewerCountText(scope)){ return svgs[i]; }
304+
scope = scope.parentElement;
305+
}
306+
}
307+
return null;
308+
}
309+
285310
function isSsappContext(){
286311
try {
287312
if (window.ninjafy || window.electronApi || window.__ssapp){ return true; }
@@ -293,10 +318,61 @@
293318

294319
function nameFromAlt(img){
295320
if (!img || !img.alt){ return ""; }
296-
return (img.alt + "")
321+
var alt = (img.alt + "").trim();
322+
var englishName = alt
297323
.replace(/[']s profile picture.*$/i, "")
298324
.replace(/[']s profile photo.*$/i, "")
299325
.trim();
326+
if (englishName && (englishName !== alt)){ return englishName; }
327+
328+
var localizedName = alt
329+
.replace(/^.*\bperfil\b\s+(de|del|do|da)\s+/i, "")
330+
.replace(/^.*\bprofil\b\s+(de|du|von)\s+/i, "")
331+
.replace(/^.*\bprofile\b\s+(of)\s+/i, "")
332+
.trim();
333+
if (localizedName && (localizedName !== alt)){ return localizedName; }
334+
return alt;
335+
}
336+
337+
function isLikelyProfileImage(img){
338+
if (!img || !img.src){ return false; }
339+
var alt = ((img.alt || "") + "").toLowerCase();
340+
if ((alt.indexOf("profile picture") !== -1) || (alt.indexOf("profile photo") !== -1)){ return true; }
341+
if ((alt.indexOf("perfil") !== -1) || (alt.indexOf("profil") !== -1)){ return true; }
342+
if (img.closest && img.closest("[role='link'], a[href]")){ return true; }
343+
return false;
344+
}
345+
346+
function getProfileImgCandidates(scope){
347+
var candidates = [];
348+
if (!scope || !scope.querySelectorAll){ return candidates; }
349+
var imgs = scope.querySelectorAll(PROFILE_IMG_FALLBACK_SELECTOR);
350+
for (var i = 0; i < imgs.length; i++){
351+
if (isLikelyProfileImage(imgs[i])){ candidates.push(imgs[i]); }
352+
}
353+
return candidates;
354+
}
355+
356+
function getProfileImgFromRow(row){
357+
if (!row || !row.querySelector){ return null; }
358+
var img = row.querySelector(PROFILE_IMG_SELECTOR);
359+
if (img){ return img; }
360+
var candidates = getProfileImgCandidates(row);
361+
if (candidates.length){ return candidates[0]; }
362+
return row.querySelector(PROFILE_IMG_FALLBACK_SELECTOR);
363+
}
364+
365+
function findLiveUsername(row, profileImg){
366+
var altName = nameFromAlt(profileImg);
367+
var leaves = collectTextLeaves(row);
368+
for (var i = 0; i < leaves.length; i++){
369+
var text = normalizeLiveText(leaves[i].textContent || "");
370+
if (!text){ continue; }
371+
if (altName && (text.toLowerCase() === altName.toLowerCase())){ return text; }
372+
if (text.length > 80){ continue; }
373+
return text;
374+
}
375+
return altName;
300376
}
301377

302378
// Walk up from an element until we find the comment row container.
@@ -319,15 +395,15 @@
319395
function looksLikeRow(node){
320396
if (!node || !node.querySelector){ return false; }
321397
if (node.querySelector("header, video, footer")){ return false; }
322-
var pics = node.querySelectorAll(PROFILE_IMG_SELECTOR);
398+
var pics = getProfileImgCandidates(node);
323399
if (pics.length !== 1){ return false; }
324400
return true;
325401
}
326402

327403
function findLiveRows(){
328404
var rows = [];
329405
var seen = new Set();
330-
var imgs = document.querySelectorAll("section " + PROFILE_IMG_SELECTOR);
406+
var imgs = document.querySelectorAll("section " + PROFILE_IMG_FALLBACK_SELECTOR);
331407
for (var i = 0; i < imgs.length; i++){
332408
var row = rowFromImage(imgs[i]);
333409
if (!row){ continue; }
@@ -447,9 +523,9 @@
447523
function parseLiveRow(row){
448524
if (!row || !row.querySelector){ return null; }
449525

450-
var profileImg = row.querySelector(PROFILE_IMG_SELECTOR) || row.querySelector("img[src]");
526+
var profileImg = getProfileImgFromRow(row) || row.querySelector("img[src]");
451527
var chatimg = profileImg ? (profileImg.src + "") : "";
452-
var chatname = nameFromAlt(profileImg);
528+
var chatname = findLiveUsername(row, profileImg);
453529
var chatmessage = "";
454530
var streamEvent = false;
455531
var messageLeaf = null;
@@ -542,7 +618,7 @@
542618
var targetSection = null;
543619
for (var i = 0; i < sections.length; i++) {
544620
var section = sections[i];
545-
if (section.querySelectorAll(PROFILE_IMG_SELECTOR).length > 0) {
621+
if (getProfileImgCandidates(section).length > 0) {
546622
targetSection = section;
547623
break;
548624
}
@@ -599,7 +675,7 @@
599675
function checkViewers(){
600676
if (!(settings.showviewercount || settings.hypemode)){ return; }
601677
try {
602-
var icon = document.querySelector("svg[aria-label='Viewer count icon']");
678+
var icon = findViewerCountIcon();
603679
if (!icon){ return; }
604680
// Walk upward and look for a nearby numeric span in the header.
605681
var scope = icon.closest("header") || icon.parentElement;
@@ -739,7 +815,7 @@
739815
if (!isElementVisible(node)){ continue; }
740816
var clickable = closestClickable(node);
741817
if (!clickable || !isElementVisible(clickable)){ continue; }
742-
if (!clickable.querySelector("img[alt*='profile picture'], img[alt*='profile photo'], canvas")){ continue; }
818+
if (!clickable.querySelector("canvas") && !getProfileImgCandidates(clickable).length){ continue; }
743819
return clickable;
744820
}
745821
return null;

0 commit comments

Comments
 (0)