From 80e050e976d6bc69a3f05df8eee1418f2268e99c Mon Sep 17 00:00:00 2001 From: Stijn Peeters Date: Fri, 15 Nov 2024 13:46:52 +0100 Subject: [PATCH 1/7] Fessebouc --- images/platform-icons/facebook.png | Bin 0 -> 3778 bytes modules/facebook.js | 63 +++++++++++++++++++++++++++++ 2 files changed, 63 insertions(+) create mode 100644 images/platform-icons/facebook.png create mode 100644 modules/facebook.js diff --git a/images/platform-icons/facebook.png b/images/platform-icons/facebook.png new file mode 100644 index 0000000000000000000000000000000000000000..7cc9404e92c367b80b23a1a7069d781dc0d0c2df GIT binary patch literal 3778 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 sv<(! Date: Tue, 1 Jul 2025 22:56:39 +0800 Subject: [PATCH 2/7] add parse_ to clean unwanted data --- modules/facebook.js | 72 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 71 insertions(+), 1 deletion(-) diff --git a/modules/facebook.js b/modules/facebook.js index 0046124..f5c8e98 100644 --- a/modules/facebook.js +++ b/modules/facebook.js @@ -12,6 +12,76 @@ zeeschuimer.register_module( let edges = []; const type_list = ['SOCIAL_POSTS', 'POSTS_SET_FEATURED', 'PUBLIC_POSTS']; + const parse_ = function (obj){ + const exactKeysToRemove = new Set([ + "encrypted_tracking", + "click_tracking_linkshim_cb", + "encrypted_click_tracking", + "comet_footer_renderer", + "actor_provider", + "trackingdata", + "viewability_config", + "client_view_config", + "accessibility_caption", + "reaction_display_config", + "accent_color", + "focus" + ]); + + function shouldRemoveKey(key) { + return ( + exactKeysToRemove.has(key) || + key.startsWith("__") || + key.startsWith("ghl") || + key.startsWith("viewer_") + ); + } + + function deepClean(target) { + if (Array.isArray(target)) { + for (let i = target.length - 1; i >= 0; i--) { + const item = target[i]; + if (typeof item === "object" && item !== null) { + deepClean(item); + if (isEmpty(item)) { + target.splice(i, 1); // Delete empty items + } + } else if (item === null || item === undefined) { + target.splice(i, 1); + } + } + } else if (target && typeof target === "object") { + for (const key of Object.keys(target)) { + if (shouldRemoveKey(key)) { + delete target[key]; + } else { + const value = target[key]; + if (typeof value === "object" && value !== null) { + deepClean(value); + if (isEmpty(value)) { + delete target[key]; + } + } + } + } + } + } + + function isEmpty(value) { + if (Array.isArray(value)) { + return value.length === 0; + } else if (value && typeof value === "object") { + return Object.keys(value).length === 0; + } + return false; + } + + const cloned = structuredClone(obj); + deepClean(cloned); + return cloned; + + } + try { datas.push(JSON.parse(response)); } catch (e) { @@ -20,7 +90,7 @@ zeeschuimer.register_module( const lines = response.split('\n'); for (const line of lines) { try { - datas.push(JSON.parse(line)); + datas.push(parse_(JSON.parse(line))); } catch (e) { } } From 896720c4d08da2fe6e09a69af739f9c9202d86bb Mon Sep 17 00:00:00 2001 From: andyfcx Date: Tue, 1 Jul 2025 23:14:02 +0800 Subject: [PATCH 3/7] rename to parse_story --- modules/facebook.js | 65 ++++++++++++++++++++------------------------- 1 file changed, 29 insertions(+), 36 deletions(-) diff --git a/modules/facebook.js b/modules/facebook.js index f5c8e98..67fc07e 100644 --- a/modules/facebook.js +++ b/modules/facebook.js @@ -2,17 +2,7 @@ zeeschuimer.register_module( 'Facebook (posts)', 'facebook.com', function (response, source_platform_url, source_url) { - let domain = source_platform_url.split("/")[2].toLowerCase().replace(/^www\./, ''); - - if (!["facebook.com"].includes(domain) || !source_url.endsWith('api/graphql/')) { - return []; - } - - let datas = []; - let edges = []; - const type_list = ['SOCIAL_POSTS', 'POSTS_SET_FEATURED', 'PUBLIC_POSTS']; - - const parse_ = function (obj){ + function parse_story(obj) { const exactKeysToRemove = new Set([ "encrypted_tracking", "click_tracking_linkshim_cb", @@ -21,13 +11,9 @@ zeeschuimer.register_module( "actor_provider", "trackingdata", "viewability_config", - "client_view_config", - "accessibility_caption", - "reaction_display_config", - "accent_color", - "focus" + "client_view_config" ]); - + function shouldRemoveKey(key) { return ( exactKeysToRemove.has(key) || @@ -36,7 +22,7 @@ zeeschuimer.register_module( key.startsWith("viewer_") ); } - + function deepClean(target) { if (Array.isArray(target)) { for (let i = target.length - 1; i >= 0; i--) { @@ -44,7 +30,7 @@ zeeschuimer.register_module( if (typeof item === "object" && item !== null) { deepClean(item); if (isEmpty(item)) { - target.splice(i, 1); // Delete empty items + target.splice(i, 1); } } else if (item === null || item === undefined) { target.splice(i, 1); @@ -66,7 +52,7 @@ zeeschuimer.register_module( } } } - + function isEmpty(value) { if (Array.isArray(value)) { return value.length === 0; @@ -75,23 +61,33 @@ zeeschuimer.register_module( } return false; } - + const cloned = structuredClone(obj); deepClean(cloned); return cloned; - } + let domain = source_platform_url.split("/")[2].toLowerCase().replace(/^www\./, ''); + + if (!["facebook.com"].includes(domain) || !source_url.endsWith('api/graphql/')) { + return []; + } + + let datas = []; + let edges = []; + const type_list = ['SOCIAL_POSTS', 'POSTS_SET_FEATURED', 'PUBLIC_POSTS']; + try { datas.push(JSON.parse(response)); } catch (e) { if (response.substring(0, 1) === '{') { - //ndjson const lines = response.split('\n'); for (const line of lines) { try { - datas.push(parse_(JSON.parse(line))); + datas.push(JSON.parse(line)); } catch (e) { + // silently ignore bad lines + console.log(e); } } } @@ -99,20 +95,16 @@ zeeschuimer.register_module( const traverse = function (obj) { for (const property in obj) { - if (!obj.hasOwnProperty(property)) { - // not actually a property - continue; - } + if (!obj.hasOwnProperty(property)) continue; - if(obj['id'] && obj['__typename'] === 'Story' && obj['comet_sections']) { + if (obj['id'] && obj['__typename'] === 'Story' && obj['comet_sections']) { + edges.push(parse_story(obj)); console.log(obj); - edges.push(obj); - } else if (typeof (obj[property]) === "object") { + } else if (typeof obj[property] === "object") { traverse(obj[property]); } } - } - + }; for (const data of datas) { if (data) { @@ -120,14 +112,15 @@ zeeschuimer.register_module( } } - for(const index in edges) { + for (const index in edges) { try { const better_id = atob(edges[index]['id']); edges[index]['id'] = better_id; } catch (e) { - // pass + // fail quietly } } + return edges; } -); \ No newline at end of file +); From 656a99b1a229a439fd552c2bb5dbd1eace876807 Mon Sep 17 00:00:00 2001 From: andyfcx Date: Tue, 1 Jul 2025 23:33:25 +0800 Subject: [PATCH 4/7] Delete more unwanted keys, enable in manifest --- manifest.json | 3 ++- modules/facebook.js | 6 +++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/manifest.json b/manifest.json index ffb9632..49531b3 100644 --- a/manifest.json +++ b/manifest.json @@ -44,7 +44,8 @@ "modules/douyin.js", "modules/gab.js", "modules/truth.js", - "modules/threads.js" + "modules/threads.js", + "modules/facebook.js" ] } } diff --git a/modules/facebook.js b/modules/facebook.js index 67fc07e..5ee01c3 100644 --- a/modules/facebook.js +++ b/modules/facebook.js @@ -11,7 +11,11 @@ zeeschuimer.register_module( "actor_provider", "trackingdata", "viewability_config", - "client_view_config" + "client_view_config", + "accessibility_caption", + "accent_color", + "focus", + "comment_composer_placeholder" ]); function shouldRemoveKey(key) { From a84a80cca9554cd33805eb71148e67540a13c2df Mon Sep 17 00:00:00 2001 From: andyfcx Date: Wed, 2 Jul 2025 00:13:29 +0800 Subject: [PATCH 5/7] fix comma --- manifest.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/manifest.json b/manifest.json index 0c0ef94..d411e39 100644 --- a/manifest.json +++ b/manifest.json @@ -46,7 +46,7 @@ "modules/gab.js", "modules/truth.js", "modules/threads.js", - "modules/facebook.js" + "modules/facebook.js", "modules/pinterest.js", "modules/rednote.js", "modules/rednote-comments.js" From 0b77196c5bcca34bf35a012c09c8efb8c5600f45 Mon Sep 17 00:00:00 2001 From: andyfcx Date: Tue, 15 Jul 2025 10:58:04 +0800 Subject: [PATCH 6/7] Enable FB by default --- js/zs-background.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/js/zs-background.js b/js/zs-background.js index 63c966b..88d965b 100644 --- a/js/zs-background.js +++ b/js/zs-background.js @@ -247,3 +247,7 @@ browser.browserAction.onClicked.addListener(async () => { browser.tabs.update(tab.id, {active: true}); } }); + +browser.runtime.onInstalled.addListener(() => { + browser.storage.local.set({ 'zs-enabled-facebook.com': '1' }); +}); \ No newline at end of file From b518258550236abf6caa3a4443bb71fea11ff69d Mon Sep 17 00:00:00 2001 From: andyfcx Date: Mon, 28 Jul 2025 12:02:18 +0800 Subject: [PATCH 7/7] Try deduplicate --- modules/facebook.js | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/modules/facebook.js b/modules/facebook.js index 5ee01c3..ab88f64 100644 --- a/modules/facebook.js +++ b/modules/facebook.js @@ -2,6 +2,8 @@ zeeschuimer.register_module( 'Facebook (posts)', 'facebook.com', function (response, source_platform_url, source_url) { + // 用於追蹤已處理的貼文 ID,避免重複 + const processedIds = new Set(); function parse_story(obj) { const exactKeysToRemove = new Set([ "encrypted_tracking", @@ -102,8 +104,12 @@ zeeschuimer.register_module( if (!obj.hasOwnProperty(property)) continue; if (obj['id'] && obj['__typename'] === 'Story' && obj['comet_sections']) { - edges.push(parse_story(obj)); - console.log(obj); + // 檢查是否已經處理過這個 ID + if (!processedIds.has(obj['id'])) { + processedIds.add(obj['id']); + edges.push(parse_story(obj)); + console.log(obj); + } } else if (typeof obj[property] === "object") { traverse(obj[property]); }