Before/after add TriCheckBoxes instead of ToggleButtons, add style removal script, + misc

This commit is contained in:
octospacc 2023-08-10 15:57:15 +02:00
parent 2990141c8e
commit fa4ad589cf
15 changed files with 407 additions and 25 deletions

View File

@ -7,7 +7,7 @@ android {
defaultConfig {
applicationId "org.eu.octt.browserocto"
minSdkVersion 1
targetSdkVersion 30
targetSdkVersion 28
versionCode 999
versionName "999.999.999"
}

View File

@ -4,8 +4,11 @@
package="org.eu.octt.browserocto"
android:versionCode="1"
android:versionName="1.0.1">
<uses-sdk android:minSdkVersion="1" android:targetSdkVersion="30"/>
<uses-sdk android:minSdkVersion="1" android:targetSdkVersion="28"/>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<!-- TODO maybe we can target SDK 30+ if we implement this: https://stackoverflow.com/questions/65876736/how-do-you-request-manage-external-storage-permission-in-android -->
<!-- <uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"/> -->
<uses-permission android:name="com.android.launcher.permission.INSTALL_SHORTCUT"/>
<application
android:allowBackup="true"

View File

@ -11,6 +11,9 @@ import android.util.*;
import java.util.*;
import android.content.*;
import android.text.*;
import java.io.*;
import android.widget.CompoundButton.*;
import android.graphics.*;
public class BrowserActivity extends Activity
{
@ -29,6 +32,9 @@ public class BrowserActivity extends Activity
CurSiteSettings = Settings;
}
WebView Weber;
View LayNamespacedSettings;
@Override
protected void onCreate(Bundle savedInstanceState)
{
@ -50,10 +56,15 @@ public class BrowserActivity extends Activity
EditOmnibar.setInputType(InputType.TYPE_CLASS_TEXT);
EditOmnibar.setMaxLines(1);
EditOmnibar.setLayoutParams(new TableRow.LayoutParams(0, LayoutParams.WRAP_CONTENT, 1.0f));
EditOmnibar.setHint(R.string.HintOmnibar);
EditOmnibar.setText("https://example.com");
LayOmni.addView(EditOmnibar);
final WebView Weber = new WebView(this);
final TriCheckBox Testbox = new TriCheckBox(this);
//Testbox.setBinary();
LayMain.addView(Testbox);
/*final WebView*/ Weber = new WebView(this);
LayMain.addView(Weber);
EditOmnibar.setOnKeyListener(new OnKeyListener() {
@ -100,7 +111,7 @@ public class BrowserActivity extends Activity
DefSiteSettings.PolyfillCss = false;
DefSiteSettings.Devtools = false;
SiteSettingsCollection.put("Default", DefSiteSettings);
SetCurSiteSettings(GetDefSiteSettings());
CurSiteSettings = DefSiteSettings;
/*final TextView ITest = new TextView(this);
ITest.setText("Test");
@ -142,22 +153,38 @@ public class BrowserActivity extends Activity
};
});
final CheckBox CheckOptBlockBadware = (CheckBox)_Util.AddLayoutChild(_Util.MakeCheckBox(this, DefSiteSettings.BlockBadware, "Block Badware"), LayOpt);
final CheckBox CheckOptSuppressBanners = (CheckBox)_Util.AddLayoutChild(_Util.MakeCheckBox(this, DefSiteSettings.SuppressBanners, "Suppress Cookie Banners"), LayOpt);
final CheckBox CheckOptAllowJs = (CheckBox)_Util.AddLayoutChild(_Util.MakeCheckBox(this, DefSiteSettings.AllowJs, "Allow JavaScript/WASM"), LayOpt);
final CheckBox CheckOptAllowCss = (CheckBox)_Util.AddLayoutChild(_Util.MakeCheckBox(this, DefSiteSettings.AllowCss, "Allow Styles"), LayOpt);
final CheckBox CheckOptAllowStorage = (CheckBox)_Util.AddLayoutChild(_Util.MakeCheckBox(this, DefSiteSettings.AllowStorage, "Allow Site Storage"), LayOpt);
final CheckBox CheckOptAutofill = (CheckBox)_Util.AddLayoutChild(_Util.MakeCheckBox(this, DefSiteSettings.Autofill, "Fields Autofill"), LayOpt);
final CheckBox CheckOptForceCache = (CheckBox)_Util.AddLayoutChild(_Util.MakeCheckBox(this, DefSiteSettings.ForceCache, "Force Offline Caching"), LayOpt);
final CheckBox CheckOptSitetweaks = (CheckBox)_Util.AddLayoutChild(_Util.MakeCheckBox(this, DefSiteSettings.Sitetweaks, "SiteTweaks"), LayOpt);
final CheckBox CheckOptPolyfillJs = (CheckBox)_Util.AddLayoutChild(_Util.MakeCheckBox(this, DefSiteSettings.PolyfillJs, "Polyfill JavaScript"), LayOpt);
final CheckBox CheckOptPolyfillCss = (CheckBox)_Util.AddLayoutChild(_Util.MakeCheckBox(this, DefSiteSettings.PolyfillCss, "Polyfill CSS"), LayOpt);
final CheckBox CheckOptDevtools = (CheckBox)_Util.AddLayoutChild(_Util.MakeCheckBox(this, DefSiteSettings.Devtools, "DevTools"), LayOpt);
final Button BtnOptCustomJs = (Button)_Util.AddLayoutChild(_Util.MakeButton(this, "Custom JavaScript"), LayOpt);
final Button BtnOptCustomCss = (Button)_Util.AddLayoutChild(_Util.MakeButton(this, "Custom CSS"), LayOpt);
final Button BtnOptCustomRedirects = (Button)_Util.AddLayoutChild(_Util.MakeButton(this, "Custom Redirects"), LayOpt);
/*View*/ LayNamespacedSettings = getLayoutInflater().inflate(R.layout.webnamespacesettings, null);
LayOpt.addView(LayNamespacedSettings);
//setContentView(R.layout.webnamespacesettings);
//(CheckBox)LayOpt.findViewById("CheckDevtools").setText("Test");
//final GridLayout LayOptNamespaced = (GridLayout)_Util.AddLayoutChild(new GridLayout(this), LayOpt);
//LayOptNamespaced.setColumnCount(2);
//final ToggleButton ToggleCheckOptBlockBadware = (ToggleButton)_Util.AddLayoutChild(_Util.MakeToggleButton(this, false, false), LayOptNamespaced);
//final CheckBox CheckOptBlockBadware = (CheckBox)_Util.AddLayoutChild(_Util.MakeCheckBox(this, DefSiteSettings.BlockBadware, "Block Badware"), LayOptNamespaced);
//final CheckBox CheckOptSuppressBanners = (CheckBox)_Util.AddLayoutChild(_Util.MakeCheckBox(this, DefSiteSettings.SuppressBanners, "Suppress Cookie Banners"), LayOpt);
//final CheckBox CheckOptAllowJs = (CheckBox)_Util.AddLayoutChild(_Util.MakeCheckBox(this, DefSiteSettings.AllowJs, "Allow JavaScript/WASM"), LayOpt);
//final CheckBox CheckOptAllowCss = (CheckBox)_Util.AddLayoutChild(_Util.MakeCheckBox(this, DefSiteSettings.AllowCss, "Allow Styles"), LayOpt);
//final CheckBox CheckOptAllowStorage = (CheckBox)_Util.AddLayoutChild(_Util.MakeCheckBox(this, DefSiteSettings.AllowStorage, "Allow Site Storage"), LayOpt);
//final CheckBox CheckOptAutofill = (CheckBox)_Util.AddLayoutChild(_Util.MakeCheckBox(this, DefSiteSettings.Autofill, "Fields Autofill"), LayOpt);
//////final CheckBox CheckOptForceCache = (CheckBox)_Util.AddLayoutChild(_Util.MakeCheckBox(this, DefSiteSettings.ForceCache, "Force Offline Caching"), LayOpt);
//final CheckBox CheckOptSitetweaks = (CheckBox)_Util.AddLayoutChild(_Util.MakeCheckBox(this, DefSiteSettings.Sitetweaks, "SiteTweaks"), LayOpt);
//final CheckBox CheckOptPolyfillJs = (CheckBox)_Util.AddLayoutChild(_Util.MakeCheckBox(this, DefSiteSettings.PolyfillJs, "Polyfill JavaScript"), LayOpt);
//final CheckBox CheckOptPolyfillCss = (CheckBox)_Util.AddLayoutChild(_Util.MakeCheckBox(this, DefSiteSettings.PolyfillCss, "Polyfill CSS"), LayOpt);
//final CheckBox CheckOptDevtools = (CheckBox)_Util.AddLayoutChild(_Util.MakeCheckBox(this, DefSiteSettings.Devtools, "DevTools"), LayOpt);
//final Button BtnOptCustomJs = (Button)_Util.AddLayoutChild(_Util.MakeButton(this, "Custom JavaScript"), LayOpt);
//final Button BtnOptCustomCss = (Button)_Util.AddLayoutChild(_Util.MakeButton(this, "Custom CSS"), LayOpt);
//final Button BtnOptCustomRedirects = (Button)_Util.AddLayoutChild(_Util.MakeButton(this, "Custom Redirects"), LayOpt);
UpdateNamespacedOpts();
_Util.Cast(LayNamespacedSettings.findViewById(R.id.CheckOptDevtools), CheckBox.class).setOnCheckedChangeListener(new OnCheckedChangeListener(){
@Override
public void onCheckedChanged(CompoundButton Check, boolean Checked){
if (Checked) {
}
}
});
final PopupWindow PopOpt = new PopupWindow(this);
PopOpt.setContentView(_LayOpt);
@ -216,10 +243,73 @@ public class BrowserActivity extends Activity
};
});
ApplyWebSettings();
Weber.setWebViewClient(new WebViewClient() {
@Override
public void onPageStarted(WebView Web, String Url, Bitmap Icon){
if (Url.toLowerCase().startsWith("browserocto://")) {
Web.addJavascriptInterface(this, "browseroctoJsi");
//
} else
Web.removeJavascriptInterface("browseroctoJsi");
}
@Override
public void onPageFinished(WebView Web, String Url){
if (!CurSiteSettings.AllowCss)
WebInhibitStyles();
Web.evaluateJavascript("alert(1);document.body.innerHTML+='TESTING'", null);
}
});
Weber.loadUrl(EditOmnibar.getText().toString());
//Weber.getSettings().setJavaScriptEnabled(CurSiteSettings.AllowJs);
};
private void UpdateNamespacedOpts(){
_Util.Cast(LayNamespacedSettings.findViewById(R.id.CheckOptBlockBadware), CheckBox.class).setChecked(CurSiteSettings.BlockBadware);
_Util.Cast(LayNamespacedSettings.findViewById(R.id.CheckOptSuppressBanners), CheckBox.class).setChecked(CurSiteSettings.SuppressBanners);
_Util.Cast(LayNamespacedSettings.findViewById(R.id.CheckOptAllowJs), CheckBox.class).setChecked(CurSiteSettings.AllowJs);
_Util.Cast(LayNamespacedSettings.findViewById(R.id.CheckOptAllowCss), CheckBox.class).setChecked(CurSiteSettings.AllowCss);
_Util.Cast(LayNamespacedSettings.findViewById(R.id.CheckOptDevtools), CheckBox.class).setChecked(CurSiteSettings.Devtools);
}
private void ApplyWebSettings(){
Weber.getSettings().setJavaScriptEnabled(CurSiteSettings.AllowJs);
if (CurSiteSettings.AllowCss)
WebRestoreStyles();
else
WebInhibitStyles();
Weber.getSettings().setDomStorageEnabled(CurSiteSettings.AllowStorage);
}
private void WebInhibitStyles(){
Weber.evaluateJavascript(_Util.OpenRawResourceString(getResources(), R.raw.webinhibitstyles), null);
}
private void WebRestoreStyles(){
Weber.evaluateJavascript(_Util.OpenRawResourceString(getResources(), R.raw.webinhibitstyles), null);
}
private void WebLoadDevtools(){
File Injectable = new File("/data/data/" + getPackageName() + "/files/", "eruda.js");
if (!Injectable.exists()) {
AskDownloadRequirement(Injectable.getPath(), new String[]{"https://example.com/eruda.js"});
}
if (Injectable.exists()) {
try {
Weber.evaluateJavascript(_Util.StreamToString(new FileInputStream(Injectable)), null);
} catch(Exception Ex){
}
}
}
@JavascriptInterface
private void AskDownloadRequirement(String Path, String Urls[]){
//popup download request
}
/*
@Override
public boolean onCreateOptionsMenu(Menu menu) {

View File

@ -54,6 +54,17 @@ public class MainActivity extends Activity
startActivity(new Intent(getApplicationContext(), BrowserActivity.class));
}
});
findViewById(R.id.BtnUpdates).setOnClickListener(new OnClickListener(){
@Override
public void onClick(View v){
// download our updates csv
// for line in csv
// split Name;Uri;Version;LocalPath;Urls[;];
// check Version date > current version date of file
// if yes direct to URL / ask to download
}
});
};
private Intent MakeIntBrowse(String Url, Boolean Cache) {

View File

@ -0,0 +1,100 @@
package org.eu.octt.browserocto;
import android.widget.*;
import android.content.*;
import android.util.*;
// <http://stackoverflow.com/questions/16511535/ddg#40939367>
public class TriCheckBox extends CheckBox {
static private final int UNKNOW = -1;
static private final int UNCHECKED = 0;
static private final int CHECKED = 1;
static private final int DrawableUndefined = R.drawable.checkbox_undefined; //R.drawable.ic_checkbox_indeterminate_black;
static private final int DrawableUnchecked = R.drawable.checkbox_unchecked; //android.R.drawable.checkbox_off_background;
static private final int DrawableChecked = R.drawable.checkbox_checked; //android.R.drawable.checkbox_on_background;
private int state;
private boolean binary = false; // allow emulating a binary checkbox
public TriCheckBox(Context context) {
super(context);
init();
}
public TriCheckBox(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public TriCheckBox(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
private void init() {
state = BinTriDef();
updateBtn();
setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
// checkbox status is changed from uncheck to checked.
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
switch (state) {
default:
case UNKNOW:
state = UNCHECKED;
break;
case UNCHECKED:
state = CHECKED;
break;
case CHECKED:
state = BinTriDef();
break;
}
updateBtn();
}
});
}
private void updateBtn() {
int btnDrawable = DrawableUndefined;
switch (state) {
default:
case UNKNOW:
btnDrawable = DrawableUndefined;
break;
case UNCHECKED:
btnDrawable = DrawableUnchecked;
break;
case CHECKED:
btnDrawable = DrawableChecked;
break;
}
setButtonDrawable(btnDrawable);
}
private int BinTriDef() {
if (binary)
return UNCHECKED;
else
return UNKNOW;
}
public int getState() {
return state;
}
public void setState(int state) {
this.state = state;
updateBtn();
}
public boolean getBinary() {
return binary;
}
public void setBinary(boolean binary) {
this.binary = binary;
init();
}
}

View File

@ -7,6 +7,7 @@ import java.io.*;
import android.graphics.drawable.*;
import android.util.*;
import android.view.*;
import android.content.res.*;
public class _Util extends Activity
{
@ -60,6 +61,18 @@ public class _Util extends Activity
return "";
};
public static String TryStreamToString(InputStream In){
try {
return StreamToString(In);
} catch (IOException Ex) {
return null;
}
}
public static String OpenRawResourceString(Resources Res, int Id){
return TryStreamToString(Res.openRawResource(Id));
}
// https://stackoverflow.com/a/10857407
public static void WriteStreamToFile(InputStream In, String Path, String Name) throws IOException {
try {
@ -100,6 +113,15 @@ public class _Util extends Activity
return Btn;
};
public static ToggleButton MakeToggleButton(Context c, Boolean Checked, Boolean Enabled){
ToggleButton Toggle = new ToggleButton(c);
if (Checked != null)
Toggle.setChecked(Checked);
if (Enabled != null)
Toggle.setEnabled(Enabled);
return Toggle;
};
public static RadioButton MakeRadioButton(Context c, Boolean Checked, String Text){
RadioButton Radio = new RadioButton(c);
Radio.setText(Text);
@ -116,8 +138,27 @@ public class _Util extends Activity
return Check;
};
public static View AddLayoutChild(View Child, LinearLayout Parent) {
Parent.addView(Child);
public static View AddLayoutChild(View Child, View Parent){
if (Parent.getClass() == LinearLayout.class || Parent.getClass() == RadioGroup.class) {
LinearLayout _Parent = (LinearLayout)Parent;
_Parent.addView(Child);
};
if (Parent.getClass() == GridLayout.class) {
GridLayout _Parent = (GridLayout)Parent;
_Parent.addView(Child);
};
//_Parent.addView(Child);
//public static View AddLayoutChild(View Child, LinearLayout Parent){
// Parent.addView(Child);
return Child;
}
};
// <https://stackoverflow.com/a/14524815>
public static <T> T Cast(Object o, Class<T> clazz) {
try {
return clazz.cast(o);
} catch(ClassCastException e) {
return null;
}
};
};

Binary file not shown.

After

Width:  |  Height:  |  Size: 320 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 227 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 222 B

View File

@ -54,5 +54,12 @@
android:padding="10dp"
android:id="@+id/BtnExperimental"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Check Updates"
android:id="@+id/BtnUpdates"
android:visibility="gone"/>
</LinearLayout>

View File

@ -0,0 +1,59 @@
<?xml version="1.0" encoding="utf-8"?>
<GridLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:columnCount="2">
<ToggleButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/ToggleCheckOptBlockBadware"/>
<CheckBox
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/CheckOptBlockBadware"
android:text="@string/LabelBlockBadware"/>
<ToggleButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/ToggleCheckOptSuppressBanners"/>
<CheckBox
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/CheckOptSuppressBanners"
android:text="@string/LabelSuppressBanners"/>
<ToggleButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/ToggleCheckOptAllowJs"/>
<CheckBox
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/CheckOptAllowJs"
android:text="@string/LabelAllowJs"/>
<ToggleButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/ToggleCheckOptAllowCss"/>
<CheckBox
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/CheckOptAllowCss"
android:text="@string/LabelAllowCss"/>
<ToggleButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/ToggleCheckOptDevtools"/>
<CheckBox
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/CheckOptDevtools"
android:text="@string/LabelDevtools"/>
</GridLayout>

View File

@ -0,0 +1,54 @@
// <https://stackoverflow.com/a/9252908>
function RemoveInlineStyles(El) {
El.removeAttribute('style');
if (El.childNodes.length > 0) {
for (let Child in El.childNodes) {
/* filter element nodes only */
if (El.childNodes[Child].nodeType == 1)
RemoveInlineStyles(El.childNodes[Child]);
};
};
};
function RemoveStyleSheets() {
for (let El of document.getElementsByTagName('link')) {
if (String(El.getAttribute('rel')).toLowerCase() == 'stylesheet' || String(El.getAttribute('type')).toLowerCase() == 'text/css')
El.parentNode.removeChild(El);
};
for (let El of document.getElementsByTagName('style')) {
El.parentNode.removeChild(El);
};
};
function InhibitInlineStyles(El) {
El.setAttribute('browseroctodisabledstyle', El.getAttribute('style'));
El.removeAttribute('style');
if (El.childNodes.length > 0) {
for (let Child in El.childNodes) {
/* filter element nodes only */
if (El.childNodes[Child].nodeType == 1)
InhibitInlineStyles(El.childNodes[Child]);
};
};
};
function InhibitStyleSheets() {
for (let El of document.getElementsByTagName('link')) {
if (String(El.getAttribute('rel')).toLowerCase() == 'stylesheet' || String(El.getAttribute('type')).toLowerCase() == 'text/css')
ChangeElementTag(El);
};
for (let El of document.getElementsByTagName('style')) {
ChangeElementTag(El);
};
};
function ChangeElementTag(El) {
let NewTag = `browseroctodisabled${El.tagName}`;
El.outerHTML = `<${NewTag}${El.outerHTML.split(El.tagName).slice(1, -1).join(El.tagName)}${NewTag}>`;
};
//RemoveInlineStyles(document.body);
//RemoveStyleSheets();
InhibitInlineStyles(document.body);
InhibitStyleSheets();

View File

View File

@ -2,4 +2,4 @@
<resources>
<style name="AppTheme" parent="@android:style/Theme.Material.Light">
</style>
</resources>
</resources>

View File

@ -1,4 +1,21 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">browserocto</string>
</resources>
<string name="HintOmnibar">Search or enter URL...</string>
<string name="LabelBlockBadware">Block Badware</string>
<string name="LabelSuppressBanners">Suppress Cookie Banners</string>
<string name="LabelAllowJs">Allow JavaScript/WASM</string>
<string name="LabelAllowCss">Allow Styles</string>
<string name="LabelAllowStorage">Allow Site Storage</string>
<string name="LabelAutofill">Fields Autofill</string>
<string name="LabelForceCache">Force Offline Caching</string>
<string name="LabelSitetweaks">SiteTweaks</string>
<string name="LabelPolyfillHtml">Polyfill HTML</string>
<string name="LabelPolyfillJs">Polyfill/Downcompile JS</string>
<string name="LabelPolyfillCss">Polyfill CSS</string>
<!--<string name="LabelPolyfillList">Polyfill: </string>-->
<string name="LabelDevtools">DevTools</string>
<string name="LabelCustomJs">Custom JS</string>
<string name="LabelCustomCss">Custom CSS</string>
<string name="LabelCustomRedirects">Custom Redirects</string>
</resources>