aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAllan Wang <me@allanwang.ca>2017-06-16 00:53:10 -0700
committerAllan Wang <me@allanwang.ca>2017-06-16 00:53:10 -0700
commitb9ea80d5b5a06d050ce2c7ca46ed597f4cb499ff (patch)
tree95a8519b719a37dfb791bb6771c940a11e9f7e9e
parentf84a05f8aeb73ce63f77b7cc779845c31427b2b2 (diff)
downloadfrost-b9ea80d5b5a06d050ce2c7ca46ed597f4cb499ff.tar.gz
frost-b9ea80d5b5a06d050ce2c7ca46ed597f4cb499ff.tar.bz2
frost-b9ea80d5b5a06d050ce2c7ca46ed597f4cb499ff.zip
Add listener logic
-rw-r--r--app/src/main/assets/.gitignore1
-rw-r--r--app/src/main/assets/js/click_interceptor.js16
-rw-r--r--app/src/main/assets/js/click_interceptor.min.js10
-rw-r--r--app/src/main/assets/js/click_interceptor_bak.js14
-rw-r--r--app/src/main/assets/js/menu.js73
-rw-r--r--app/src/main/assets/js/menu.min.js28
-rw-r--r--app/src/main/assets/js/menu_click.js15
-rw-r--r--app/src/main/assets/js/menu_click.min.js9
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/injectors/JsActions.kt2
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/injectors/JsAssets.kt2
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/injectors/JsInjector.kt7
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/web/FrostJSI.kt9
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/web/FrostWebViewClient.kt12
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/web/FrostWebViewClientMenu.kt33
14 files changed, 147 insertions, 84 deletions
diff --git a/app/src/main/assets/.gitignore b/app/src/main/assets/.gitignore
new file mode 100644
index 00000000..62c89355
--- /dev/null
+++ b/app/src/main/assets/.gitignore
@@ -0,0 +1 @@
+.idea/ \ No newline at end of file
diff --git a/app/src/main/assets/js/click_interceptor.js b/app/src/main/assets/js/click_interceptor.js
index 68dbac2b..238b31d3 100644
--- a/app/src/main/assets/js/click_interceptor.js
+++ b/app/src/main/assets/js/click_interceptor.js
@@ -1,13 +1,15 @@
// generic click handler
-document.onclick = function(e) {
+document.on('click', function (e) {
e = e || window.event;
+ e.preventDefault();
var element = e.target || e.srcElement;
if (element.tagName !== 'A')
- element = element.parentNode;
+ element = element.parentNode;
if (element.tagName === 'A') {
- var url = element.href;
- console.log('Generic Click Intercept');
- console.log(url);
- Frost.loadUrl(url);
+ var url = element.href;
+ console.log('Generic Click Intercept');
+ console.log(url);
+ // Frost.loadUrl(url);
}
-};
+ return false;
+});
diff --git a/app/src/main/assets/js/click_interceptor.min.js b/app/src/main/assets/js/click_interceptor.min.js
index 5f10dd2b..3acb9265 100644
--- a/app/src/main/assets/js/click_interceptor.min.js
+++ b/app/src/main/assets/js/click_interceptor.min.js
@@ -1 +1,9 @@
-document.onclick=function(c){c=c||window.event;var b=c.target||c.srcElement;if(b.tagName!=="A"){b=b.parentNode}if(b.tagName==="A"){var a=b.href;console.log("Generic Click Intercept");console.log(a);Frost.loadUrl(a)}}; \ No newline at end of file
+document.querySelector("body").addEventListener("click",function(e){
+e=e||window.event
+;var t=e.target||e.srcElement
+;if("A"!==t.tagName&&(t=t.parentNode),"A"===t.tagName){
+var n=t.href
+;console.log("Generic Click Intercept"),console.log(n)
+}
+return!1
+}); \ No newline at end of file
diff --git a/app/src/main/assets/js/click_interceptor_bak.js b/app/src/main/assets/js/click_interceptor_bak.js
new file mode 100644
index 00000000..d541ccd2
--- /dev/null
+++ b/app/src/main/assets/js/click_interceptor_bak.js
@@ -0,0 +1,14 @@
+// generic click handler
+document.onclick = function(e) {
+ e = e || window.event;
+ var element = e.target || e.srcElement;
+ if (element.tagName !== 'A')
+ element = element.parentNode;
+ if (element.tagName === 'A') {
+ var url = element.href;
+ console.log('Generic Click Intercept');
+ console.log(url);
+ // Frost.loadUrl(url);
+ }
+ return false;
+};
diff --git a/app/src/main/assets/js/menu.js b/app/src/main/assets/js/menu.js
index 2c517ed2..4a39a93b 100644
--- a/app/src/main/assets/js/menu.js
+++ b/app/src/main/assets/js/menu.js
@@ -1,35 +1,38 @@
-var viewport = document.getElementById('viewport');
-var root = document.getElementById('root');
-var y = new MutationObserver(function(mutations) {
- viewport.removeAttribute('style');
- root.removeAttribute('style');
-});
-y.observe(viewport, {
- attributes: true
-});
-y.observe(root, {
- attributes: true
-});
-var x = new MutationObserver(function(mutations) {
- var menuChildren = document.getElementsByClassName('mSideMenu');
- if (menuChildren.length > 0) {
- x.disconnect();
- console.log('Found side menu');
- var menu = menuChildren[0];
- while (root.firstChild)
- root.removeChild(root.firstChild);
- while (menu.childNodes.length)
- root.appendChild(menu.childNodes[0]);
- Frost.emit(0);
- setTimeout(function() {
- y.disconnect();
- console.log('Unhook styler');
- Frost.handleHtml(document.documentElement.outerHTML);
- }, 500);
- }
-});
-x.observe(document.getElementById('mJewelNav'), {
- childList: true,
- subtree: true
-});
-document.getElementById('bookmarks_jewel').getElementsByTagName('a')[0].click();
+if (document.querySelector('#mJewelNav') !== null) {
+ console.log('Fetching menu');
+ var viewport = document.querySelector('#viewport');
+ var root = document.querySelector('#root');
+ var y = new MutationObserver(function(mutations) {
+ viewport.removeAttribute('style');
+ root.removeAttribute('style');
+ });
+ y.observe(viewport, {
+ attributes: true
+ });
+ y.observe(root, {
+ attributes: true
+ });
+ var x = new MutationObserver(function(mutations) {
+ var menu = document.querySelector('.mSideMenu');
+ if (menu !== null) {
+ x.disconnect();
+ console.log('Found side menu');
+ while (root.firstChild)
+ root.removeChild(root.firstChild);
+ while (menu.childNodes.length)
+ root.appendChild(menu.childNodes[0]);
+ Frost.emit(0);
+ setTimeout(function() {
+ y.disconnect();
+ console.log('Unhook styler');
+ Frost.handleHtml(document.documentElement.outerHTML);
+ }, 500);
+ }
+ });
+ x.observe(document.querySelector('#mJewelNav'), {
+ childList: true,
+ subtree: true
+ });
+ document.querySelector('#bookmarks_jewel').querySelector('a').click();
+}
+//otherwise we've already found the side nav and this is unnecessary
diff --git a/app/src/main/assets/js/menu.min.js b/app/src/main/assets/js/menu.min.js
index 7aa05351..0f218ea5 100644
--- a/app/src/main/assets/js/menu.min.js
+++ b/app/src/main/assets/js/menu.min.js
@@ -1 +1,27 @@
-var viewport=document.getElementById("viewport");var root=document.getElementById("root");var y=new MutationObserver(function(a){viewport.removeAttribute("style");root.removeAttribute("style")});y.observe(viewport,{attributes:true});y.observe(root,{attributes:true});var x=new MutationObserver(function(a){var c=document.getElementsByClassName("mSideMenu");if(c.length>0){x.disconnect();console.log("Found side menu");var b=c[0];while(root.firstChild){root.removeChild(root.firstChild)}while(b.childNodes.length){root.appendChild(b.childNodes[0])}Frost.emit(0);setTimeout(function(){y.disconnect();console.log("Unhook styler");Frost.handleHtml(document.documentElement.outerHTML)},500)}});x.observe(document.getElementById("mJewelNav"),{childList:true,subtree:true});document.getElementById("bookmarks_jewel").getElementsByTagName("a")[0].click(); \ No newline at end of file
+if(null!==document.querySelector("#mJewelNav")){
+console.log("Fetching menu")
+;var viewport=document.querySelector("#viewport"),root=document.querySelector("#root"),y=new MutationObserver(function(e){
+viewport.removeAttribute("style"),
+root.removeAttribute("style")
+})
+;y.observe(viewport,{
+attributes:!0
+}),y.observe(root,{
+attributes:!0
+})
+;var x=new MutationObserver(function(e){
+var o=document.querySelector(".mSideMenu")
+;if(null!==o){
+for(x.disconnect(),console.log("Found side menu");root.firstChild;)root.removeChild(root.firstChild)
+;for(;o.childNodes.length;)root.appendChild(o.childNodes[0])
+;Frost.emit(0),setTimeout(function(){
+y.disconnect(),console.log("Unhook styler"),
+Frost.handleHtml(document.documentElement.outerHTML)
+},500)
+}
+})
+;x.observe(document.querySelector("#mJewelNav"),{
+childList:!0,
+subtree:!0
+}),document.querySelector("#bookmarks_jewel").querySelector("a").click()
+} \ No newline at end of file
diff --git a/app/src/main/assets/js/menu_click.js b/app/src/main/assets/js/menu_click.js
index 3e23617a..82041b0e 100644
--- a/app/src/main/assets/js/menu_click.js
+++ b/app/src/main/assets/js/menu_click.js
@@ -1,16 +1,15 @@
// we will handle click events
-document.onclick = function(e) {
- e = e || window.event;
+console.log('Registering menu click');
+document.addEventListener('click', function(e) {
var element = e.target || e.srcElement;
if (element.tagName !== 'A')
element = element.parentNode;
- if (element.tagName === 'A') {
+ if (element.tagName === 'A' && element.getAttribute('href') !== '#') {
var url = element.href;
console.log('Click Intercept');
console.log(url);
- if (url !== "https://m.facebook.com/settings" && url !== "https://m.facebook.com/settings#" && url !== "https://m.facebook.com/settings#!/settings?soft=bookmarks") {
- Frost.loadUrl(url);
- Frost.reloadBaseUrl(false); //reinject base view
- }
+ Frost.loadUrl(url);
+ e.stopPropagation();
+ e.preventDefault();
}
-};
+}, true);
diff --git a/app/src/main/assets/js/menu_click.min.js b/app/src/main/assets/js/menu_click.min.js
index 580f0467..4d508f71 100644
--- a/app/src/main/assets/js/menu_click.min.js
+++ b/app/src/main/assets/js/menu_click.min.js
@@ -1 +1,8 @@
-document.onclick=function(c){c=c||window.event;var b=c.target||c.srcElement;if(b.tagName!=="A"){b=b.parentNode}if(b.tagName==="A"){var a=b.href;console.log("Click Intercept");console.log(a);if(a!=="https://m.facebook.com/settings"&&a!=="https://m.facebook.com/settings#"&&a!=="https://m.facebook.com/settings#!/settings?soft=bookmarks"){Frost.loadUrl(a);Frost.reloadBaseUrl(false)}}}; \ No newline at end of file
+console.log("Registering menu click"),document.addEventListener("click",function(e){
+var t=e.target||e.srcElement
+;if("A"!==t.tagName&&(t=t.parentNode),"A"===t.tagName&&"#"!==t.getAttribute("href")){
+var o=t.href
+;console.log("Click Intercept"),console.log(o),Frost.loadUrl(o),e.stopPropagation(),
+e.preventDefault()
+}
+},!0); \ No newline at end of file
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/injectors/JsActions.kt b/app/src/main/kotlin/com/pitchedapps/frost/injectors/JsActions.kt
index 17d7ca81..70df1bfa 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/injectors/JsActions.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/injectors/JsActions.kt
@@ -1,6 +1,7 @@
package com.pitchedapps.frost.injectors
import android.webkit.WebView
+import com.pitchedapps.frost.facebook.FB_URL_BASE
/**
* Created by Allan Wang on 2017-05-31.
@@ -11,6 +12,7 @@ enum class JsActions(body: String) : InjectorContract {
* see [com.pitchedapps.frost.web.FrostJSI.loadLogin]
*/
LOGIN_CHECK("document.getElementById('signup-button')&&Frost.loadLogin();"),
+ BASE_HREF("document.write(\"<base href='$FB_URL_BASE'/>\");"),
EMPTY("");
val function = "!function(){$body}();"
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/injectors/JsAssets.kt b/app/src/main/kotlin/com/pitchedapps/frost/injectors/JsAssets.kt
index d0bf9deb..864f95ea 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/injectors/JsAssets.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/injectors/JsAssets.kt
@@ -29,4 +29,4 @@ enum class JsAssets : InjectorContract {
injector = null
}
-} \ No newline at end of file
+}
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/injectors/JsInjector.kt b/app/src/main/kotlin/com/pitchedapps/frost/injectors/JsInjector.kt
index 0000ecf1..2d8d42e1 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/injectors/JsInjector.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/injectors/JsInjector.kt
@@ -1,8 +1,7 @@
package com.pitchedapps.frost.injectors
import android.webkit.WebView
-import com.pitchedapps.frost.facebook.FbCookie
-import com.pitchedapps.frost.utils.L
+import com.pitchedapps.frost.web.FrostWebViewClient
import io.reactivex.Observable
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.subjects.SingleSubject
@@ -43,7 +42,7 @@ interface InjectorContract {
/**
* Helper method to inject multiple functions simultaneously with a single callback
*/
-fun WebView.jsInject(vararg injectors: InjectorContract, callback: ((Array<String>) -> Unit)) {
+fun WebView.jsInject(vararg injectors: InjectorContract, callback: ((Array<String>) -> Unit) = {}) {
val observables = Array(injectors.size, { SingleSubject.create<String>() })
Observable.zip<String, Array<String>>(observables.map { it.toObservable() }, { it.map { it.toString() }.toTypedArray() }).subscribeOn(AndroidSchedulers.mainThread()).subscribe({
callback.invoke(it)
@@ -54,6 +53,8 @@ fun WebView.jsInject(vararg injectors: InjectorContract, callback: ((Array<Strin
}
}
+fun FrostWebViewClient.jsInject(vararg injectors: InjectorContract, callback: ((Array<String>) -> Unit) = {}) = webCore.jsInject(*injectors, callback = callback)
+
class JsInjector(val function: String) : InjectorContract {
override fun inject(webView: WebView, callback: ((String) -> Unit)?) {
webView.evaluateJavascript(function, { value -> callback?.invoke(value) })
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/web/FrostJSI.kt b/app/src/main/kotlin/com/pitchedapps/frost/web/FrostJSI.kt
index bb482c3c..f81c6a15 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/web/FrostJSI.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/web/FrostJSI.kt
@@ -19,8 +19,15 @@ class FrostJSI(val context: Context, val webView: FrostWebViewCore) {
val cookies: ArrayList<CookieModel>
get() = (context as? MainActivity)?.cookies() ?: arrayListOf()
+ var lastUrl: String = ""
+
@JavascriptInterface
- fun loadUrl(url: String) = context.launchWebOverlay(url)
+ fun loadUrl(url: String) {
+ if (url != lastUrl) {
+ lastUrl = url
+ context.launchWebOverlay(url)
+ }
+ }
@JavascriptInterface
fun reloadBaseUrl(animate: Boolean) {
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/web/FrostWebViewClient.kt b/app/src/main/kotlin/com/pitchedapps/frost/web/FrostWebViewClient.kt
index 07b9a949..8cd36b86 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/web/FrostWebViewClient.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/web/FrostWebViewClient.kt
@@ -62,7 +62,7 @@ open class FrostWebViewClient(val webCore: FrostWebViewCore) : WebViewClient() {
L.d("Page finished reveal")
webCore.jsInject(CssHider.HEADER,
Prefs.themeInjector,
- JsAssets.CLICK_INTERCEPTOR,
+// JsAssets.CLICK_INTERCEPTOR,
callback = {
L.d("Finished ${it.contentToString()}")
refreshObservable.onNext(false)
@@ -77,14 +77,6 @@ open class FrostWebViewClient(val webCore: FrostWebViewCore) : WebViewClient() {
L.d("Emit $flag")
}
- fun inject(jsAssets: JsAssets, view: WebView, callback: (String) -> Unit = {}) {
- L.i("Post inject ${jsAssets.name}")
- jsAssets.inject(view, {
- L.i("Post injection done $it")
- callback.invoke(it)
- })
- }
-
override fun shouldOverrideKeyEvent(view: WebView, event: KeyEvent): Boolean {
L.d("Key event ${event.keyCode}")
return super.shouldOverrideKeyEvent(view, event)
@@ -95,6 +87,8 @@ open class FrostWebViewClient(val webCore: FrostWebViewCore) : WebViewClient() {
return super.shouldOverrideUrlLoading(view, request)
}
+
+
override fun shouldInterceptRequest(view: WebView, request: WebResourceRequest?): WebResourceResponse? {
if (request == null || !(request.url.host?.contains(FACEBOOK_COM) ?: false)) return super.shouldInterceptRequest(view, request)
L.v("Url intercept ${request.url.path}")
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/web/FrostWebViewClientMenu.kt b/app/src/main/kotlin/com/pitchedapps/frost/web/FrostWebViewClientMenu.kt
index 9a00c563..2a1a5b74 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/web/FrostWebViewClientMenu.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/web/FrostWebViewClientMenu.kt
@@ -2,7 +2,9 @@ package com.pitchedapps.frost.web
import android.graphics.Bitmap
import android.webkit.WebView
+import com.pitchedapps.frost.facebook.FB_URL_BASE
import com.pitchedapps.frost.injectors.JsAssets
+import com.pitchedapps.frost.injectors.jsInject
import com.pitchedapps.frost.utils.L
import io.reactivex.subjects.Subject
@@ -13,17 +15,18 @@ class FrostWebViewClientMenu(webCore: FrostWebViewCore) : FrostWebViewClient(web
var content: String? = null
val progressObservable: Subject<Int> = webCore.progressObservable
+ private val contentBaseUrl = "https://touch.facebook.com/notifications"
override fun onPageStarted(view: WebView, url: String, favicon: Bitmap?) {
super.onPageStarted(view, url, favicon)
if (content != null) {
- when (url) {
- "https://m.facebook.com/settings",
- "https://m.facebook.com/settings#",
- "https://m.facebook.com/settings#!/settings?soft=bookmarks" -> {
+ when (url.removePrefix(FB_URL_BASE)) {
+ "settings",
+ "settings#",
+ "settings#!/settings?soft=bookmarks" -> {
L.d("Load from stored $url")
view.stopLoading()
- view.loadDataWithBaseURL("https://touch.facebook.com/notifications", content, "text/html", "utf-8", "https://google.ca/test")
+ view.loadDataWithBaseURL(contentBaseUrl, content, "text/html", "utf-8", "https://google.ca/test")
}
}
}
@@ -31,27 +34,23 @@ class FrostWebViewClientMenu(webCore: FrostWebViewCore) : FrostWebViewClient(web
override fun onPageFinished(view: WebView, url: String) {
super.onPageFinished(view, url)
- if (url == webCore.baseUrl) {
- progressObservable.onNext(99)
- inject(JsAssets.MENU, webCore, {
- inject(JsAssets.MENU_CLICK, webCore) //menu injection must be after or we will have a loop from the click listener
+ if (url == webCore.baseUrl && content == null) {
+ jsInject(JsAssets.MENU, callback = {
+ jsInject(JsAssets.MENU_CLICK) //menu injection must be after or we will have a loop from the click listener
})
- } else {
- inject(JsAssets.MENU_CLICK, webCore)
- }
+ } else if (url == contentBaseUrl) jsInject(JsAssets.MENU_CLICK)
}
override fun emit(flag: Int) {
super.emit(flag)
- progressObservable.onNext(100)
super.injectAndFinish()
}
override fun onPageFinishedActions(url: String?) {
- when (url) {
- "https://m.facebook.com/settings",
- "https://m.facebook.com/settings#",
- "https://m.facebook.com/settings#!/settings?soft=bookmarks" -> {
+ when (url?.removePrefix(FB_URL_BASE)) {
+ "settings",
+ "settings#",
+ "settings#!/settings?soft=bookmarks" -> {
//do nothing; we will further inject before revealing
}
else -> injectAndFinish()