Skip to content

Commit c5d13a0

Browse files
author
hoang.tran12
committed
pip full website
1 parent 01b2d19 commit c5d13a0

File tree

7 files changed

+169
-26
lines changed

7 files changed

+169
-26
lines changed

manifest.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
"default_icon": "./assets/icon32.png"
1515
},
1616
"permissions": [
17+
"tts",
1718
"power",
1819
"tabs",
1920
"storage",
@@ -25,13 +26,13 @@
2526
"scripting",
2627
"tabCapture",
2728
"contextMenus",
29+
"desktopCapture",
2830
"webNavigation",
2931
"notifications",
3032
"unlimitedStorage",
3133
"declarativeNetRequest",
3234
"declarativeNetRequestFeedback",
33-
"declarativeNetRequestWithHostAccess",
34-
"*://*/*"
35+
"declarativeNetRequestWithHostAccess"
3536
],
3637
"host_permissions": ["<all_urls>"],
3738
"options_page": "./pages/options/options.html",

popup/tabs.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,7 @@ const tabs = [
269269
// s.youtube_localDownloader,
270270
s.youtube_downloadVideo,
271271
s.pictureInPicture,
272+
s.pip_fullWebsite,
272273
s.youtube_toggleLight,
273274
s.youtube_viewDislikes,
274275
s.youtube_nonstop,

scripts/background-scripts/background-script.js

Lines changed: 2 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -127,23 +127,10 @@ function main() {
127127
try {
128128
if (request.action === "ufs-runInBackground") {
129129
const { params = [], fnPath = "" } = request.data || {};
130-
let fn = fnPath?.startsWith("chrome") ? chrome : GLOBAL;
131-
fnPath.split(".").forEach((part) => {
132-
fn = fn?.[part] || fn;
133-
});
134130
console.log("runInBackground", fnPath, params);
135-
let res = fn?.(...params);
136-
137-
if (typeof res?.then === "function") {
138-
res.then?.((_res) => {
139-
console.log(_res);
140-
sendResponse(_res);
141-
});
142-
} else {
143-
console.log(res);
131+
utils.runFunc(fnPath, params, GLOBAL).then((res) => {
144132
sendResponse(res);
145-
}
146-
133+
});
147134
return true;
148135
}
149136
} catch (e) {

scripts/content-scripts/content_script.js

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
import("./ufs_global.js");
1+
import("./ufs_global.js"); // to use UfsGlobal inside content-script
2+
let utils;
23

34
// communication between page-script and content-script
45
function sendToPageScript(event, uuid, data) {
@@ -26,6 +27,13 @@ async function runScript(scriptId, event) {
2627
}
2728

2829
(async () => {
30+
async function getUtils() {
31+
if (!utils) utils = await import("../helpers/utils.js");
32+
return utils;
33+
}
34+
35+
getUtils(); // import and save utils
36+
2937
chrome.runtime.onMessage.addListener(function (
3038
message,
3139
sender,
@@ -51,12 +59,9 @@ async function runScript(scriptId, event) {
5159
switch (event) {
5260
case "ufs-runInContentScript":
5361
const { params = [], fnPath = "" } = data || {};
54-
let fn = fnPath?.startsWith?.("chrome") ? chrome : window;
55-
fnPath.split(".").forEach((part) => {
56-
fn = fn?.[part] || fn;
57-
});
5862
console.log("runInContentScript", fnPath, params);
59-
sendToPageScript(event, uuid, await fn?.(...params));
63+
const res = await (await getUtils()).runFunc(fnPath, params);
64+
sendToPageScript(event, uuid, res);
6065
break;
6166
case "ufs-runInBackground":
6267
chrome.runtime.sendMessage(

scripts/helpers/utils.js

Lines changed: 36 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,44 @@
1-
// Utils used by popup and background-script
1+
// Utils used by popup and background-script (and content-script?)
22

3-
const { version } = chrome.runtime.getManifest();
3+
const { version } = chrome.runtime?.getManifest() || {};
4+
5+
export function runFunc(fnPath = "", params = [], global = {}) {
6+
return new Promise((resolve) => {
7+
let fn = fnPath?.startsWith("chrome") ? chrome : global;
8+
fnPath.split(".").forEach((part) => {
9+
fn = fn?.[part] || fn;
10+
});
11+
12+
let hasCallback = false;
13+
let _params = params.map((p) => {
14+
if (p === "callback") {
15+
hasCallback = true;
16+
return resolve;
17+
}
18+
return p;
19+
});
20+
let res = fn?.(..._params);
21+
22+
if (!hasCallback) {
23+
if (typeof res?.then === "function") {
24+
res.then?.((_res) => {
25+
console.log(_res);
26+
resolve(_res);
27+
});
28+
} else {
29+
console.log(res);
30+
resolve(res);
31+
}
32+
}
33+
});
34+
}
435

536
export async function trackEvent(scriptId) {
6-
console.log("trackEvent", scriptId);
37+
console.log("trackEvent", scriptId, version);
38+
return;
739
try {
840
let res = await fetch(
41+
// "http://localhost:3000/count",
942
"https://useful-script-statistic.glitch.me/count",
1043
// "https://useful-script-statistic.onrender.com/count",
1144
{

scripts/index.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,7 @@ import textToQrCode from "./textToQrCode.js";
162162
import insta_anonymousStoryViewer from "./insta_anonymousStoryViewer.js";
163163
import removeWebLimit from "./removeWebLimit.js";
164164
import _ufs_statistic from "./_ufs_statistic.js";
165+
import pip_fullWebsite from "./pip_fullWebsite.js";
165166

166167
// inject badges
167168
const allScripts = {
@@ -340,6 +341,7 @@ const allScripts = {
340341
insta_anonymousStoryViewer: addBadge(insta_anonymousStoryViewer, BADGES.new),
341342
removeWebLimit: addBadge(removeWebLimit, BADGES.hot),
342343
_ufs_statistic: _ufs_statistic,
344+
pip_fullWebsite: addBadge(pip_fullWebsite, BADGES.new),
343345
};
344346

345347
// alert(Object.keys(allScripts).length);

scripts/pip_fullWebsite.js

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
export default {
2+
icon: "https://lh3.googleusercontent.com/cvfpnTKw3B67DtM1ZpJG2PNAIjP6hVMOyYy403X4FMkOuStgG1y4cjCn21vmTnnsip1dTZSVsWBA9IxutGuA3dVDWhg=w128-h128-e365-rj-sc0x00ffffff",
3+
name: {
4+
en: "PIP full website",
5+
vi: "PIP toàn website",
6+
},
7+
description: {
8+
en: "Picture in picture mode for full website",
9+
vi: "Picture in picture: Xem toàn bộ website (thay vì chỉ video) trong của sổ nhỏ",
10+
img: "",
11+
},
12+
13+
changeLogs: [
14+
{
15+
version: "1.66",
16+
date: "25/04/2024",
17+
description: {
18+
en: "init",
19+
vi: "init",
20+
},
21+
},
22+
],
23+
24+
onClickContentScript: async () => {
25+
if (!window.ufs_pip_fullWebsite) {
26+
window.ufs_pip_fullWebsite = {
27+
isPIP: false,
28+
video: null,
29+
stream: null,
30+
};
31+
}
32+
33+
function enterPIP(stream, video) {
34+
window.ufs_pip_fullWebsite.isPIP = true;
35+
window.ufs_pip_fullWebsite.video = video;
36+
window.ufs_pip_fullWebsite.stream = stream;
37+
video.requestPictureInPicture();
38+
}
39+
40+
function leavePIP() {
41+
document.exitPictureInPicture();
42+
window.ufs_pip_fullWebsite.isPIP = false;
43+
window.ufs_pip_fullWebsite.video?.remove?.();
44+
window.ufs_pip_fullWebsite.stream?.getVideoTracks?.().forEach((track) => {
45+
track.stop();
46+
});
47+
window.ufs_pip_fullWebsite.stream = null;
48+
}
49+
50+
try {
51+
if (window.ufs_pip_fullWebsite.isPIP) {
52+
leavePIP();
53+
return;
54+
}
55+
56+
const tab = await UfsGlobal.Extension.runInBackground(
57+
"utils.getCurrentTab"
58+
);
59+
60+
const streamId = await UfsGlobal.Extension.runInBackground(
61+
"chrome.tabCapture.getMediaStreamId",
62+
[
63+
{
64+
targetTabId: tab.id,
65+
consumerTabId: tab.id,
66+
},
67+
]
68+
);
69+
70+
navigator.webkitGetUserMedia(
71+
{
72+
audio: false,
73+
video: {
74+
mandatory: {
75+
chromeMediaSource: "tab", // The media source must be 'tab' here.
76+
chromeMediaSourceId: streamId,
77+
minWidth: 50,
78+
minHeight: 50,
79+
// maxWidth: 1920,
80+
// maxHeight: 1080,
81+
minFrameRate: 10,
82+
maxFrameRate: 60,
83+
},
84+
},
85+
},
86+
function (stream) {
87+
const video = document.createElement("video");
88+
video.srcObject = stream;
89+
video.autoplay = true;
90+
video.style.display = "none";
91+
video.addEventListener("enterpictureinpicture", () => {});
92+
video.addEventListener("leavepictureinpicture", () => {
93+
leavePIP();
94+
});
95+
video.addEventListener(
96+
"canplay",
97+
function () {
98+
this.play();
99+
enterPIP(stream, video);
100+
},
101+
{ once: true }
102+
);
103+
document.body.appendChild(video);
104+
},
105+
function (error) {
106+
alert("ERROR: " + error);
107+
console.log(error);
108+
}
109+
);
110+
} catch (e) {
111+
alert(e);
112+
}
113+
},
114+
};

0 commit comments

Comments
 (0)