Skip to content

Commit

Permalink
drop support slide={number} feature and remove whole ads from sites
Browse files Browse the repository at this point in the history
  • Loading branch information
mkusaka committed Oct 27, 2023
1 parent 5659ef9 commit b3a781b
Show file tree
Hide file tree
Showing 7 changed files with 21 additions and 227 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -104,3 +104,5 @@ dist
.tern-port

content.js

_metadata
5 changes: 1 addition & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,7 @@ Chrome extension which provides a better slideshare experience

## features

- remove ad in slide
- hide special offer modal
- add `slide={pageNumber}` format suffix & if you reload this page, current page will be shown again.
- prefetch images
- remove ad in whole site

# chrome store

Expand Down
202 changes: 0 additions & 202 deletions content.ts
Original file line number Diff line number Diff line change
@@ -1,206 +1,4 @@
import { createBrowserHistory } from "history";
import Cookies from "js-cookie";

const history = createBrowserHistory();

function getPropsData() {
const propsElement = document.getElementById("__NEXT_DATA__");
const propsJSON = JSON.parse(propsElement.innerHTML);
return propsJSON;
}

function seekIframeInfo() {
const iframeEmbed:
| {
height: number;
width: number;
url: string;
}
| undefined = getPropsData()?.props?.pageProps?.slideshow?.iframeEmbed;
if (!iframeEmbed) {
console.log("cannot find valid iframeEmbed");
return null;
}

return iframeEmbed;
}

function parseSlideParam() {
const { search } = history.location;
const slide = new URLSearchParams(search).get("slide");
if (typeof slide === "string") {
return parseInt(slide, 10);
}
return null;
}

function generateURL(url: string, slide: number) {
const parsedURL = new URL(url);
parsedURL.searchParams.set("startSlide", slide);
return parsedURL.toString();
}

function proxyClickEventToSlideIFrame(event: Event) {
const iframe = document.querySelector("#iframe-rfs");
const rect = iframe.getBoundingClientRect();
const x = event.clientX - rect.left;
const y = event.clientY - rect.top;

// Access to elements in iframe
const iframeDocument =
iframe.contentDocument || iframe.contentWindow.document;
const clickedElement = iframeDocument.elementFromPoint(x, y);
if (clickedElement) {
// Simulate click event
clickedElement.dispatchEvent(
new MouseEvent("click", {
bubbles: true,
cancelable: true,
view: iframe.contentWindow,
}),
);
}
}

function getSlideNumber() {
// parse slide params
const urlSearchParams = new URLSearchParams(window.location.search);
const slideNumber = urlSearchParams.get("slide");
if (slideNumber) {
return parseInt(slideNumber, 10);
}
return null;
}

function setSlideSearchParams(slideNumber: number, withDelete = false) {
// parse slide params
const urlSearchParams = new URLSearchParams(window.location.search);
if (withDelete) {
urlSearchParams.delete("slide");
} else {
urlSearchParams.set("slide", slideNumber);
}
return urlSearchParams;
}

function prefetchImages() {
const slideImages =
getPropsData()?.props?.pageProps?.slideshow?.slideImages || [];

const fragment = document.createDocumentFragment();
for (let i = 0; i < slideImages.length; i++) {
const link = document.createElement("link");
link.rel = "prefetch";
link.href = slideImages[i].webpSrcset.split(",").map(it => it.trim().split(" ")[0]).at(-1);
fragment.appendChild(link);
}

document.head.appendChild(fragment);
}

const container = document.getElementById("new-player");
if (container) {
const iframeInfo = seekIframeInfo();
if (iframeInfo) {
const { url } = iframeInfo;
const slide = parseSlideParam();
const newURL = slide ? generateURL(url, slide) : url;
const { width, height } = container.getBoundingClientRect();
container.innerHTML = `<!-- Left overlay -->
<div style="position: absolute; width: 20%; height: calc(100% - 50px); z-index: 1; cursor: url(/images/ssplayer/left-pointer.png) 25 25,auto;" id="left-overlay-rfs"></div>
<!-- Right overlay -->
<div style="position: absolute; top: 15%; right: 0; width: 20%; height: calc(100% - 15% - 50px); z-index: 1; cursor: url(/images/ssplayer/right-pointer.png) 25 25,auto;" id="right-overlay-rfs"></div>
<iframe src="${newURL}" width="${width}" frameborder="0" marginwidth="0" marginheight="0" scrolling="no" style="border:1px solid #CCC; border-width:1px; margin-bottom:5px; max-width: 100%; aspect-ratio: ${width} / ${height};" allowfullscreen id="iframe-rfs">`;
const left = document.querySelector("#left-overlay-rfs");
left?.addEventListener("click", (event) => {
proxyClickEventToSlideIFrame(event);

// parse slide params
const urlSearchParams = new URLSearchParams(window.location.search);

const slideNumber = getSlideNumber();
let nextSlideNumber = 1;
if (slideNumber) {
nextSlideNumber = Math.max(slideNumber - 1, 1);
}
const url = new URL(window.location.href);
if (nextSlideNumber === 1) {
urlSearchParams.delete("slide");
url.search = urlSearchParams;
} else {
urlSearchParams.set("slide", nextSlideNumber);
url.search = urlSearchParams;
}
history.replace(url.toString());
});
document.addEventListener("keydown", (event) => {
if (event.key === "ArrowLeft") {
if (left) {
const rect = left.getBoundingClientRect();

const centerX = rect.left + rect.width / 2;
const centerY = rect.top + rect.height / 2;

const clickEvent = new MouseEvent("click", {
view: window,
bubbles: true,
cancelable: true,
clientX: centerX,
clientY: centerY,
});

left.dispatchEvent(clickEvent);
}
}
});
const right = document.querySelector("#right-overlay-rfs");
right?.addEventListener("click", (event) => {
proxyClickEventToSlideIFrame(event);

const totalSlides =
getPropsData()?.props?.pageProps?.slideshow?.totalSlides;

if (!totalSlides) {
console.log("cannot find total slides");
return;
}

// parse slide params
const urlSearchParams = new URLSearchParams(window.location.search);

const slideNumber = getSlideNumber();
let nextSlideNumber = 2;
if (slideNumber) {
nextSlideNumber = Math.min(slideNumber + 1, totalSlides);
}
const url = new URL(window.location.href);
urlSearchParams.set("slide", nextSlideNumber);
url.search = urlSearchParams;
history.replace(url.toString());
});
document.addEventListener("keydown", (event) => {
if (event.key === "ArrowRight") {
if (right) {
const rect = right.getBoundingClientRect();

const centerX = rect.left + rect.width / 2;
const centerY = rect.top + rect.height / 2;

const clickEvent = new MouseEvent("click", {
view: window,
bubbles: true,
cancelable: true,
clientX: centerX,
clientY: centerY,
});

right.dispatchEvent(clickEvent);
}
}
});
}
}

// hide modal ads as default
Cookies.set("scribd_ad_exit_slideshow_page", true);
prefetchImages();
8 changes: 7 additions & 1 deletion manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,11 @@
"js": ["content.js"]
}
],
"host_permissions": ["https://www.slideshare.net/*"]
"host_permissions": ["https://www.slideshare.net/*"],
"permissions": ["declarativeNetRequest"],
"declarative_net_request": {
"rule_resources": [
{ "id": "rules1", "path": "rules.json", "enabled": true }
]
}
}
1 change: 0 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
"watch": "esbuild content.ts --bundle --target=chrome100 --watch --outfile=content.js"
},
"dependencies": {
"history": "^5.3.0",
"js-cookie": "^3.0.5"
}
}
11 changes: 11 additions & 0 deletions rules.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
[
{
"id": 1,
"priority": 1,
"action": { "type": "block" },
"condition": {
"urlFilter": "*://a.pub.network/*",
"resourceTypes": ["script"]
}
}
]
19 changes: 0 additions & 19 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,6 @@
# yarn lockfile v1


"@babel/runtime@^7.7.6":
version "7.23.2"
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.23.2.tgz#062b0ac103261d68a966c4c7baf2ae3e62ec3885"
integrity sha512-mM8eg4yl5D6i3lu2QKPuPH4FArvJ8KhTofbE7jwMUv9KX5mBvwPAqnV3MlyBNqdp9RyRKP6Yck8TrfYrPvX3bg==
dependencies:
regenerator-runtime "^0.14.0"

"@esbuild/[email protected]":
version "0.19.5"
resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.19.5.tgz#276c5f99604054d3dbb733577e09adae944baa90"
Expand Down Expand Up @@ -177,13 +170,6 @@ esbuild@^0.19.5:
"@esbuild/win32-ia32" "0.19.5"
"@esbuild/win32-x64" "0.19.5"

history@^5.3.0:
version "5.3.0"
resolved "https://registry.yarnpkg.com/history/-/history-5.3.0.tgz#1548abaa245ba47992f063a0783db91ef201c73b"
integrity sha512-ZqaKwjjrAYUYfLG+htGaIIZ4nioX2L70ZUMIFysS3xvBsSG4x/n1V6TXV3N8ZYNuFGlDirFg32T7B6WOUPDYcQ==
dependencies:
"@babel/runtime" "^7.7.6"

js-cookie@^3.0.5:
version "3.0.5"
resolved "https://registry.yarnpkg.com/js-cookie/-/js-cookie-3.0.5.tgz#0b7e2fd0c01552c58ba86e0841f94dc2557dcdbc"
Expand All @@ -193,8 +179,3 @@ prettier@^3.0.3:
version "3.0.3"
resolved "https://registry.yarnpkg.com/prettier/-/prettier-3.0.3.tgz#432a51f7ba422d1469096c0fdc28e235db8f9643"
integrity sha512-L/4pUDMxcNa8R/EthV08Zt42WBO4h1rarVtK0K+QJG0X187OLo7l699jWw0GKuwzkPQ//jMFA/8Xm6Fh3J/DAg==

regenerator-runtime@^0.14.0:
version "0.14.0"
resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.14.0.tgz#5e19d68eb12d486f797e15a3c6a918f7cec5eb45"
integrity sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA==

0 comments on commit b3a781b

Please sign in to comment.