1
0
mirror of https://github.com/AllanWang/Frost-for-Facebook.git synced 2024-09-19 23:21:34 +02:00

Enhancement/url redirect manager (#182)

* Initial blacklist

* Move js checks to java

* Optimize imports and clean up request interceptor
This commit is contained in:
Allan Wang 2017-08-15 19:53:57 -07:00 committed by GitHub
parent 19ec9b543e
commit 2eaad9b727
7 changed files with 93 additions and 44 deletions

View File

@ -15,17 +15,16 @@ if (!window.hasOwnProperty('frost_click_a')) {
if (element.tagName !== 'A') element = element.parentNode;
//Notifications is two layers under
if (element.tagName !== 'A') element = element.parentNode;
if (element.tagName === 'A' && element.getAttribute('href') !== '#') {
var url = element.getAttribute('href');
if (url.includes('photoset_token')) return;
if (element.tagName === 'A') {
if (!prevented) {
var url = element.getAttribute('href');
console.log('Click Intercept', url);
if (typeof Frost !== 'undefined') Frost.loadUrl(url);
// if frost is injected, check if loading the url through an overlay works
if (typeof Frost !== 'undefined' && Frost.loadUrl(url)) {
e.stopPropagation();
e.preventDefault();
}
}
e.stopPropagation();
e.preventDefault();
}
}

View File

@ -4,12 +4,10 @@ window.frost_click_a=!0
;var prevented=!1,_frostAClick=function(e){
var t=e.target||e.srcElement
;if("A"!==t.tagName&&(t=t.parentNode),"A"!==t.tagName&&(t=t.parentNode),
"A"===t.tagName&&"#"!==t.getAttribute("href")){
"A"===t.tagName&&!prevented){
var n=t.getAttribute("href")
;if(n.includes("photoset_token"))return
;prevented||(console.log("Click Intercept",n),
"undefined"!=typeof Frost&&Frost.loadUrl(n)),
e.stopPropagation(),e.preventDefault()
;console.log("Click Intercept",n),"undefined"!=typeof Frost&&Frost.loadUrl(n)&&(e.stopPropagation(),
e.preventDefault())
}
},_frostPreventClick=function(){
console.log("Click prevented"),prevented=!0

View File

@ -54,6 +54,11 @@ fun Activity.cookies(): ArrayList<CookieModel> {
return intent?.extras?.getParcelableArrayList<CookieModel>(EXTRA_COOKIES) ?: arrayListOf()
}
/**
* Launches the given url in a new overlay (if it already isn't in an overlay)
* Note that most requests may need to first check if the url can be launched as an overlay
* See [requestWebOverlay] to verify the launch
*/
fun Context.launchWebOverlay(url: String) {
val argUrl = url.formattedFbUrl
L.v("Launch received", url)

View File

@ -25,10 +25,14 @@ class FrostJSI(val webView: FrostWebViewCore) {
val cookies: ArrayList<CookieModel>
get() = activity?.cookies() ?: arrayListOf()
/**
* Attempts to load the url in an overlay
* Returns {@code true} if successful, meaning the event is consumed,
* or {@code false} otherwise, meaning the event should be propagated
*/
@JavascriptInterface
fun loadUrl(url: String) {
context.launchWebOverlay(url)
}
fun loadUrl(url: String?): Boolean
= if (url == null) false else context.requestWebOverlay(url)
@JavascriptInterface
fun reloadBaseUrl(animate: Boolean) {

View File

@ -3,6 +3,8 @@ package com.pitchedapps.frost.web
import android.webkit.WebResourceRequest
import android.webkit.WebResourceResponse
import android.webkit.WebView
import ca.allanwang.kau.kotlin.LazyContext
import ca.allanwang.kau.kotlin.lazyContext
import ca.allanwang.kau.utils.use
import com.pitchedapps.frost.utils.L
import com.pitchedapps.frost.utils.Prefs
@ -19,41 +21,37 @@ import java.io.ByteArrayInputStream
private val blankResource: WebResourceResponse by lazy { WebResourceResponse("text/plain", "utf-8", ByteArrayInputStream("".toByteArray())) }
//these hosts will redirect to a blank resource
private val blacklistHost: Set<String> by lazy {
setOf(
"edge-chat.facebook.com"
)
}
private val blacklistHost: Set<String> =
setOf(
"edge-chat.facebook.com"
)
//these hosts will return null and skip logging
private val whitelistHost: Set<String> by lazy {
setOf(
"static.xx.fbcdn.net",
"m.facebook.com",
"touch.facebook.com"
)
}
private val whitelistHost: Set<String> =
setOf(
"static.xx.fbcdn.net",
"m.facebook.com",
"touch.facebook.com"
)
//these hosts will skip ad inspection
//this list does not have to include anything from the two above
private val adWhitelistHost: Set<String> by lazy {
setOf(
"scontent-sea1-1.xx.fbcdn.net"
)
private val adWhitelistHost: Set<String> =
setOf(
"scontent-sea1-1.xx.fbcdn.net"
)
private val adblock: LazyContext<Set<String>> = lazyContext {
it.assets.open("adblock.txt").bufferedReader().use { it.readLines().toSet() }
}
private var adblock: Set<String>? = null
fun shouldFrostInterceptRequest(view: WebView, request: WebResourceRequest): WebResourceResponse? {
fun WebView.shouldFrostInterceptRequest(request: WebResourceRequest): WebResourceResponse? {
val httpUrl = HttpUrl.parse(request.url?.toString() ?: return null) ?: return null
val host = httpUrl.host()
val url = httpUrl.toString()
if (blacklistHost.contains(host)) return blankResource
if (whitelistHost.contains(host)) return null
if (!adWhitelistHost.contains(host)) {
if (adblock == null) adblock = view.context.assets.open("adblock.txt").bufferedReader().use { it.readLines().toSet() }
if (adblock?.any { url.contains(it) } ?: false) return blankResource
}
if (!adWhitelistHost.contains(host) && adblock(context).any { url.contains(it) }) return blankResource
if (!shouldLoadImages && !Prefs.loadMediaOnMeteredNetwork && request.isMedia) return blankResource
L.v("Intercept Request", "$host $url")
return null

View File

@ -0,0 +1,48 @@
package com.pitchedapps.frost.web
import android.content.Context
import com.pitchedapps.frost.facebook.formattedFbUrl
import com.pitchedapps.frost.utils.L
import com.pitchedapps.frost.utils.isFacebookUrl
import com.pitchedapps.frost.utils.launchWebOverlay
/**
* Created by Allan Wang on 2017-08-15.
*
* Due to the nature of facebook href's, many links
* cannot be resolved on a new window and must instead
* by loaded in the current page
* This helper method will collect all known cases and launch the overlay accordingly
* Returns {@code true} (default) if overlay is launcher, {@code false} otherwise
*/
fun Context.requestWebOverlay(url: String): Boolean {
if (url == "#") return false
/*
* Non facebook urls can be loaded
*/
if (!url.formattedFbUrl.isFacebookUrl) {
launchWebOverlay(url)
L.d("Request web overlay is not a facebook url", url)
return true
}
/*
* Check blacklist
*/
if (overlayBlacklist.any { url.contains(it) }) return false
/*
* Facebook messages have the following cases for the tid query
* mid* or id* for newer threads, which can be launched in new windows
* or a hash for old threads, which must be loaded on old threads
*/
if (url.contains("/messages/read/?tid=")) {
if (!url.contains("?tid=id") && !url.contains("?tid=mid")) return false
}
L.v("Request web overlay passed", url)
launchWebOverlay(url)
return true
}
/**
* The following components should never be launched in a new overlay
*/
val overlayBlacklist = setOf("messages/?pageNum", "photoset_token")

View File

@ -11,7 +11,6 @@ import com.pitchedapps.frost.activities.LoginActivity
import com.pitchedapps.frost.activities.MainActivity
import com.pitchedapps.frost.activities.SelectorActivity
import com.pitchedapps.frost.activities.WebOverlayActivity
import com.pitchedapps.frost.facebook.FACEBOOK_COM
import com.pitchedapps.frost.facebook.FB_URL_BASE
import com.pitchedapps.frost.facebook.FbCookie
import com.pitchedapps.frost.facebook.FbItem
@ -34,7 +33,7 @@ import org.jetbrains.anko.withAlpha
open class BaseWebViewClient : WebViewClient() {
override fun shouldInterceptRequest(view: WebView, request: WebResourceRequest): WebResourceResponse?
= shouldFrostInterceptRequest(view, request)
= view.shouldFrostInterceptRequest(request)
}
@ -125,9 +124,7 @@ open class FrostWebViewClient(val webCore: FrostWebViewCore) : BaseWebViewClient
*/
private fun launchRequest(request: WebResourceRequest): Boolean {
L.d("Launching Url", request.url?.toString() ?: "null")
if (webCore.context is WebOverlayActivity) return false
webCore.context.launchWebOverlay(request.url.toString())
return true
return webCore.context !is WebOverlayActivity && webCore.context.requestWebOverlay(request.url.toString())
}
private fun launchImage(url: String, text: String? = null): Boolean {