Commit bbe7a822 authored by Tim Krief's avatar Tim Krief

Added a manifesto to explain the changes. Added rule codes from the manifesto...

Added a manifesto to explain the changes. Added rule codes from the manifesto to every change explanations. Hugely improved preprocessing tools to create a better CHANGES file. Improved README.md
parent 84e62c36
This diff is collapsed.
# This is minimal's manifesto
This manifesto is a guideline to create a more minimal internet experience. Any change made to the user experience by the minimal browser extension will be justified by one of the following rule.
This manifesto is subject to change by minimal's user community. Any suggestion can be made [here](https://gitlab.com/minimal-internet-experience/minimal/issues).
## Use
The user must actively make choices by themselves.
### 1) Interactive elements should remain informative and unbiased.
Manipulative interactive elements prevent the user from making their own choices.
### 2) A page must only have one key purpose.
Other functions must be accessed by an action of the user, not forced onto them.
### 3) Shortcuts must link to related content or actions that are hard to access.
There is no need for shortcuts that invite to use services already easily accessible and/or not obviously linked to the main content.
## Content
A user should easily find the content they are searching for on a page, not the content a platform wants them to see.
### 1) The main content of the page should stay the only focus
The user should see the main content first and foremost when landing on a page.
### 2) There should be no suggestions that have no obvious link to the main content.
If a message is not strongly linked to the main content, it is an advertisement either for suggested content or for the platform, or both, and should be signaled as such.
### 3) Additional content must be relevant.
Displaying additional unasked information can be used to change the behavior of the user.
## Platform
A service provider can convince the user to use their platform, but only through their services' inner quality.
### 1) Logos and branding visuals should remain purely informative.
Colors and graphics must not be used to create some sort of pavlovian conditioning.
### 2) Any curation process should be made in the user's interest.
A platform curation process should only help the user find interesting content. This process, if not properly disclosed, signals that a conflict of interest might be at play.
PPPath = ./preprocessing/preprocess
all: manifest.json clean zip
zip:
zip -r ./minimal.zip LICENSE README.md CHANGES.md manifest.json icons scripts styles
manifest.json: ${PPPath} data/manifestTemplate.txt data/supportedWebsites.csv data/version
${PPPath}
${PPPath}: ${PPPath}.cpp
g++ ${PPPath}.cpp -o ${PPPath}
manifest.json: preprocessing/preprocess data/manifestTemplate.txt data/supportedWebsites.csv data/version
./preprocessing/preprocess
.PHONY: ppmake
ppmake: preprocessing/preprocess
preprocessing/preprocess:
cd preprocessing && $(MAKE)
version:
cat ./data/version
......@@ -18,6 +20,6 @@ clean:
$(RM) ./minimal.zip
ppclean:
$(RM) ${PPPath}
cd preprocessing && $(MAKE) clean
deepclean: clean ppclean
![minimal logo](./pictures/logo/minimalAvatar512.png)
# Minimal, the browser extension for peace of mind
I am trying to create a minimal, less attention grabbing, internet experience.
Minimal is a browser extension to experience a minimal, less attention grabbing internet experience. Internet should be a tool, not a trap.
Minimal is driven by core values:
- The user must actively make choices by themselves.
- A user should easily find the content they are searching for on a page, not the content a platform wants them to see.
- A service provider can convince the user to use their platform, but only through their services' inner quality.
[![Get the add-on](https://addons.cdn.mozilla.net/static/img/addons-buttons/AMO-button_1.png)](https://addons.mozilla.org/firefox/addon/minimal-internet-experience/)
## The changes
To get a complete list of the changes made to the user experience by the minimal browser extension, check the [CHANGES file](./CHANGES.md). Those changes are following [minimal's manifesto](MANIFESTO.md).
A list of changes made by "minimal" is available in [CHANGES.md](./CHANGES.md)
This extension is being developed for the greater good, it is an open source project, you can check its code and contribute.
# How to contribute
## As a user
If you come across any bug or issue that seems to be caused by minimal please, report the issue [here](https://gitlab.com/timkrief/minimal/issues).
If you spot something that you think minimal should act upon on a common website let us know by creating a ticket [here](https://gitlab.com/timkrief/minimal/issues).
If you spot any particular thing that you think minimal should remove or neutralize on a common website let us know by creating a [ticket here](https://gitlab.com/timkrief/minimal/issues).
If you encounter any problem while using minimal, please create a new [issue](https://gitlab.com/timkrief/minimal/issues).
## As a (web)designer
If you have an idea about what a common website should look like or act like for it to be minimal, please, add your ideas [here](https://gitlab.com/timkrief/minimal/issues).
They will be useful to have a wider site support. Rembember, the goal is to get rid of sneaky web-design clickbaity mind-controlling techniques that influence you and make
you waste time and money by neutralizing or removing elements. Try not to add things, but to remove them.
If you have ideas about what a common website should look like or act like for it to be minimal, please, add your ideas [here](https://gitlab.com/timkrief/minimal/issues).
Please, try to follow [minimal's manifesto](./MANIFESTO.md).
## As a (web)developer
This is a browser extension, if you are not familiar about how it works, [here is a guide](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions).
When contributing, if you make a new change, add a comment to explain it. Do not edit CHANGES.md manually, the comment will be added to changes automatically.
The comment has to follow this pattern (make sure it fits in one line):
When contributing, if you make a new change, add a comment to explain it.
Do not edit CHANGES.md manually, the comment will be added to changes automatically.
The comment has to fit on one line and has to follow this pattern:
1. `/* - `
2. The explanation of the change
3. ` - `
4. A code of a rule from the [manifesto](./MANIFESTO.md)
5. ` */`
Changes must follow at least one rule from the [manifesto](./MANIFESTO.md). Rules codes are the first letter of a main section followed by the number of the rule. Multiple codes can be specifed, separated by spaces.
Exemples of the comment pattern:
```
/* - Explaination of the change - C3 P1 */
```
```
/* - Explain the change */
/* - Explaination - U2 */
```
To test the extension once changes were made, use "make" in a terminal.
To test the extension and to update the CHANGES.md file once changes were made, use "make" in a terminal.
It will generate necessary files and zip them. Then you will be able to use "minimal.zip".
......@@ -14,7 +14,7 @@
"developer": {
"name": "Tim Krief",
"url": "http://minimal.timkrief.com"
"url": "http://minimal.community"
},
"content_scripts": [
......
{
"manifest_version": 2,
"name": "minimal",
"version": "0.1.4",
"version": "0.2",
"description": "A minimal, less attention grabbing, internet experience.",
......@@ -14,7 +14,7 @@
"developer": {
"name": "Tim Krief",
"url": "http://minimal.timkrief.com"
"url": "http://minimal.community"
},
"content_scripts": [
......
......@@ -77,7 +77,7 @@
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="16"
inkscape:cx="56.574528"
inkscape:cx="88.681058"
inkscape:cy="11.303825"
inkscape:document-units="mm"
inkscape:current-layer="layer1"
......@@ -96,9 +96,9 @@
inkscape:snap-nodes="true"
inkscape:snap-bbox-midpoints="true"
inkscape:window-width="1920"
inkscape:window-height="1046"
inkscape:window-height="1018"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-y="34"
inkscape:window-maximized="1"
inkscape:snap-global="true">
<inkscape:grid
......@@ -144,6 +144,6 @@
id="tspan830-7"
x="25.774471"
y="296.22137"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:1.76388884px;font-family:'URW Gothic L';-inkscape-font-specification:'URW Gothic L';text-align:end;text-anchor:end;fill:#000000;fill-opacity:1;stroke-width:0.26458332">0.1.4</tspan></text>
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:1.76388884px;font-family:'URW Gothic L';-inkscape-font-specification:'URW Gothic L';text-align:end;text-anchor:end;fill:#000000;fill-opacity:1;stroke-width:0.26458332">0.2</tspan></text>
</g>
</svg>
pictures/logo/minimalAvatar512.png

17.8 KB | W: | H:

pictures/logo/minimalAvatar512.png

17.9 KB | W: | H:

pictures/logo/minimalAvatar512.png
pictures/logo/minimalAvatar512.png
pictures/logo/minimalAvatar512.png
pictures/logo/minimalAvatar512.png
  • 2-up
  • Swipe
  • Onion skin
sources = $(wildcard *.cpp)
objects = $(sources:.cpp=.o)
all: preprocess
preprocess: $(objects)
g++ $^ -o $@
.PHONY: clean
clean:
rm -rf $(objects) preprocess
#include "Website.h"
Website::Website(void) {}
Website::Website(std::string name) : name(name) {}
void Website::setName(std::string newName) {
name = newName;
}
std::string Website::getName(void) {
return name;
}
void Website::addTld(std::string tld) {
tlds.push_back(tld);
}
std::string Website::printUrls(void) {
std::stringstream urlList;
for (auto const& tld: tlds) {
urlList << "\"*://*." << name << "." << tld << "/*\"";
if (tld != tlds.back()) {
urlList << ", ";
}
}
return urlList.str();
}
std::string Website::printElement(void) { // Used to fill content_scripts
std::stringstream element;
element << "\t\t{" << std::endl;
element << "\t\t\t\"matches\": [" << printUrls() << "]," << std::endl;
std::string cssPath = "styles/" + name + ".css";
std::string jsPath = "scripts/" + name + ".js";
if(isFile(cssPath)){
element << "\t\t\t\"css\": [\"" << cssPath << "\"]," << std::endl;
}
if(isFile(jsPath)){
element << "\t\t\t\"js\": [\"" << jsPath << "\"]," << std::endl;
}
element << "\t\t\t\"run_at\": \"document_end\"" << std::endl;
element << "\t\t}";
return element.str();
}
std::string Website::printBackgroundScripts(void) {
std::string jsPath = "scripts/background/" + name + ".js";
if(isFile(jsPath)){
return "\"" + jsPath + "\", ";
}
return "";
}
std::string Website::printComments(std::map<std::string, std::string> &manifesto) { // Used to fill CHANGES.md
std::stringstream comments;
std::vector<std::string> filePaths;
filePaths.push_back("styles/" + name + ".css");
filePaths.push_back("scripts/" + name + ".js");
filePaths.push_back("scripts/background/" + name + ".js");
for (auto const& filePath: filePaths) {
if(isFile(filePath)){
std::ifstream file(filePath);
std::string line;
int lineNumber = 0;
while (std::getline(file, line)) {
lineNumber ++;
size_t commentStart;
std::string startString = "/* - ";
size_t commentEnd;
std::string endString = " */";
if (
(commentStart = line.find(startString, 0)) != std::string::npos &&
(commentEnd = line.find(endString, 0)) != std::string::npos
) {
commentStart += startString.length();
std::vector<std::string> commentParts = split(
line.substr(commentStart, commentEnd - commentStart), " - "
);
comments << "<details>" << std::endl << "<summary>";
comments << capitalize(commentParts[0]);
comments << "</summary>" << std::endl << std::endl;
int rulesFound = 0;
if(commentParts.size() > 1) {
std::vector<std::string> tags;
if(commentParts[1].find(" ", 0) != std::string::npos) {
tags = split(commentParts[1], " ");
} else {
tags.push_back(commentParts[1]);
}
for (auto const& tag: tags) {
if(manifesto.find(tag) != manifesto.end()) {
comments << "> « " << manifesto[tag] << " » " << std::endl;
rulesFound++;
}
}
if(rulesFound > 0){
comments << "> *From the [manifesto](MANIFESTO.md).* " << std::endl;
}
}
if(rulesFound == 0) {
comments << "> No existing rule from the [manifesto](MANIFESTO.md) has been defined for this change. " << std::endl;
}
comments << "> ___ " << std::endl;
comments << "> This change is implemented in [" << filePath << "](" << filePath << ")";
comments << " at [line " << lineNumber << "](" << filePath << "#L" << lineNumber << ").";
comments << std::endl << std::endl << "</details>" << std::endl;
}
}
file.close();
}
}
return comments.str();
}
#include "functions.h"
#include <map>
class Website {
private:
std::string name;
std::vector<std::string> tlds;
public:
Website(void);
Website(std::string name);
void setName(std::string newName);
std::string getName(void);
void addTld(std::string tld);
std::string printUrls(void);
std::string printElement(void);
std::string printBackgroundScripts(void);
std::string printComments(std::map<std::string, std::string> &manifesto);
};
#include "functions.h"
std::vector<std::string> split(const std::string stringToSplit, const std::string delimiter) {
std::vector<std::string> splits;
size_t cursor = 0;
size_t lastCursor = 0;
const int delimiterLength = delimiter.length();
while ((cursor = stringToSplit.find(delimiter, lastCursor)) != std::string::npos) {
splits.push_back(stringToSplit.substr(lastCursor, cursor-lastCursor));
lastCursor = cursor + delimiterLength;
}
splits.push_back(stringToSplit.substr(lastCursor, std::string::npos));
return splits;
}
void replace(std::string& stringToParse, const std::string stringToFind, const std::string newString) {
size_t positionFound = stringToParse.find(stringToFind);
if (positionFound != std::string::npos) {
stringToParse.replace(positionFound, stringToFind.length(), newString);
}
}
bool isFile(const std::string path) {
std::ifstream fileToCheck(path);
return !fileToCheck.fail();
}
std::string capitalize(std::string stringToCap) {
if(stringToCap.length() > 0){
stringToCap[0] = std::toupper(stringToCap[0]);
}
return stringToCap;
}
#include <string>
#include <vector>
#include <fstream>
#include <sstream>
std::vector<std::string> split(const std::string stringToSplit, const std::string delimiter);
void replace(std::string& stringToParse, const std::string stringToFind, const std::string newString);
bool isFile(const std::string path);
std::string capitalize(std::string stringToCap);
#include <iostream>
#include <string>
#include <vector>
#include <fstream>
#include <sstream>
std::vector<std::string> split(const std::string stringToSplit, const std::string delimiter) {
std::vector<std::string> splits;
size_t cursor = 0;
size_t lastCursor = 0;
const int delimiterLength = delimiter.length();
while ((cursor = stringToSplit.find(delimiter, lastCursor)) != std::string::npos) {
splits.push_back(stringToSplit.substr(lastCursor, cursor-lastCursor));
lastCursor = cursor + delimiterLength;
}
splits.push_back(stringToSplit.substr(lastCursor, std::string::npos));
return splits;
}
void replace(std::string& stringToParse, const std::string stringToFind, const std::string newString) {
size_t positionFound = stringToParse.find(stringToFind);
if (positionFound != std::string::npos) {
stringToParse.replace(positionFound, stringToFind.length(), newString);
}
}
bool isFile(const std::string path) {
std::ifstream fileToCheck(path);
return !fileToCheck.fail();
}
std::string capitalize(std::string stringToCap) {
if(stringToCap.length() > 0){
stringToCap[0] = std::toupper(stringToCap[0]);
}
return stringToCap;
}
class Website {
private:
std::string name;
std::vector<std::string> tlds;
public:
Website() {};
Website(std::string name) : name(name) {};
void setName(std::string newName) {
name = newName;
};
std::string getName(void) {
return name;
};
void addTld(std::string tld) {
tlds.push_back(tld);
};
std::string printUrls(void) {
std::stringstream urlList;
for (auto const& tld: tlds) {
urlList << "\"*://*." << name << "." << tld << "/*\"";
if (tld != tlds.back()) {
urlList << ", ";
}
}
return urlList.str();
};
std::string printElement(void) { // Used to fill content_scripts
std::stringstream element;
element << "\t\t{" << std::endl;
element << "\t\t\t\"matches\": [" << printUrls() << "]," << std::endl;
std::string cssPath = "styles/" + name + ".css";
std::string jsPath = "scripts/" + name + ".js";
if(isFile(cssPath)){
element << "\t\t\t\"css\": [\"" << cssPath << "\"]," << std::endl;
}
if(isFile(jsPath)){
element << "\t\t\t\"js\": [\"" << jsPath << "\"]," << std::endl;
}
element << "\t\t\t\"run_at\": \"document_end\"" << std::endl;
element << "\t\t}";
return element.str();
};
std::string printBackgroundScripts(void) {
std::string jsPath = "scripts/background/" + name + ".js";
if(isFile(jsPath)){
return "\"" + jsPath + "\", ";
}
return "";
};
std::string printComments(void) { // Used to fill CHANGES.md
std::stringstream comments;
std::vector<std::string> filePaths;
filePaths.push_back("styles/" + name + ".css");
filePaths.push_back("scripts/" + name + ".js");
filePaths.push_back("scripts/background/" + name + ".js");
for (auto const& filePath: filePaths) {
if(isFile(filePath)){
std::ifstream file(filePath);
std::string line;
while (std::getline(file, line)) {
size_t commentStart;
std::string startString = "/* - ";
size_t commentEnd;
std::string endString = " */";
if (
(commentStart = line.find(startString, 0)) != std::string::npos &&
(commentEnd = line.find(endString, 0)) != std::string::npos
) {
comments << "- ";
commentStart += startString.length();
comments << capitalize(line.substr(commentStart, commentEnd - commentStart));
comments << "." << std::endl;
}
}
file.close();
}
}
return comments.str();
};
};
#include "readFunctions.h"
int main(void) {
// Gather data
std::ifstream versionFile("./data/version");
std::string version;
std::getline(versionFile, version);
std::ifstream supportedWebsitesFile("./data/supportedWebsites.csv");
std::string websiteLine;
std::getline(supportedWebsitesFile, websiteLine); // Drop first line
std::vector<Website> websites;
while (std::getline(supportedWebsitesFile, websiteLine)) {
std::vector<std::string> websiteInfo = split(websiteLine, ",");
std::vector<std::string> websiteTlds = split(websiteInfo[1], " ");
websites.push_back(websiteInfo[0]);
for (auto const& tld: websiteTlds) {
websites.back().addTld(tld);
}
}
std::map<std::string, std::string> manifesto = readManifesto("./MANIFESTO.md");
std::string version = readVersion("./data/version");
std::vector<Website> websites = readSupportedWebsites("./data/supportedWebsites.csv");
// Create background and content scripts elements and url list
std::string backgroundScripts;
std::stringstream elements;
......@@ -184,7 +42,7 @@ int main(void) {
for (auto website: websites) {
std::string websiteName = website.getName();
changesFile << "# " << capitalize(websiteName) << std::endl;
changesFile << website.printComments() << std::endl;
changesFile << website.printComments(manifesto) << std::endl;
}
changesFile.close();
......
#include "readFunctions.h"
std::map<std::string, std::string> readManifesto(std::string manifestoPath){
std::ifstream manifestoFile(manifestoPath);
std::string manifestoLine;
std::map<std::string, std::string> manifesto;
std::string h2 = "";
int h3 = 0;
std::string buffer;
std::string tag = "0";
std::string previousTag = "0";
while (std::getline(manifestoFile, manifestoLine)) {
int startString = 0;
std::string beginString = "\n";
if (manifestoLine.find("### ", 0) != std::string::npos){
h3 ++;
startString = 7;
beginString = "";
} else if (manifestoLine.find("## ", 0) != std::string::npos){
h2 = manifestoLine[3];
h3 = 0;
}
if(h3 > 0){
previousTag = tag;
tag = h2 + std::to_string(h3);
if(previousTag != tag && buffer.size() > 0){
manifesto[previousTag] = buffer;
buffer = "";
}
if(manifestoLine.size() > 0){
buffer += beginString + manifestoLine.substr(startString);
}
}
}
manifesto[previousTag] = buffer;
return manifesto;
}
std::string readVersion(std::string versionPath){
std::ifstream versionFile(versionPath);
std::string version;
std::getline(versionFile, version);
return version;
}
std::vector<Website> readSupportedWebsites(std::string supportedWebsitesPath){
std::ifstream supportedWebsitesFile(supportedWebsitesPath);
std::string websiteLine;
std::getline(supportedWebsitesFile, websiteLine); // Drop first line
std::vector<Website> websites;
while (std::getline(supportedWebsitesFile, websiteLine)) {
std::vector<std::string> websiteInfo = split(websiteLine, ",");
std::vector<std::string> websiteTlds = split(websiteInfo[1], " ");
websites.push_back(websiteInfo[0]);
for (auto const& tld: websiteTlds) {
websites.back().addTld(tld);
}
}
return websites;
}
#include <iostream>
#include "Website.h"
std::map<std::string, std::string> readManifesto(std::string manifestoPath);
std::string readVersion(std::string versionPath);
std::vector<Website> readSupportedWebsites(std::string supportedWebsitesPath);
/* - Remove main page futile ad */
/* - Remove main page overwhelming fullpage suggestion - C1 */
#nav-swmslot, #desktop-banner, #nav-logo .nav-prime-try{
display: none;
}
......@@ -7,19 +7,18 @@
display: none;
}
/* - Remove product page futile ad */
/* - Remove product page arbitrary suggestions - C2 */
#detail-ilm_div{
display: none;
}
/* - Remove other futile suggestions */
/* - Remove other futile suggestions - C2 */
#sims-consolidated-1_feature_div,
#sims-consolidated-2_feature_div{
display: none;
}
/* - Use clean and neutral colors for the navbar, buttons and title */
/* - Use neutral colors for navbar */
/* - Use neutral colors for the navbar - P1 */
/* on mobile */
#nav-search-form,
#nav-logobar{
......@@ -59,7 +58,7 @@
background: lightgrey!important;
}
/* - Make logo more discrete */
/* - Make logo more discrete - P1 */
.nav-logo-base{
filter: saturate(0);
}
......@@ -68,39 +67,39 @@
opacity: 0.3;
}
/* - Make button colors neutral */
/* - Make button colors neutral - U1 */
.a-button:not(.a-button-thumbnail){
filter: grayscale(1) !important;
}
/* - Desaturate orange titles */
/* - Desaturate orange titles - P1 */
#AUI_A9AdsMiddleBoxTop h2, #CustomerDiscussions h2, #customer-discussions_feature_div h2, #customer-reviews_feature_div h2, #customerReviewsHeader, #detailpage-click2call-header, #hmdFormDiv h2, #need-help-deciding .secHeader, #pf-fitment-wrapper h2, #revMHLContainer h2, #reviewBucketHeader, #rhfMainHeading, #sponsored-products-dp_feature_div h2, .bucket h2, .cdInlineAskBoxTitle, .cdQuestionAnswerHeader, .pa_componentTitleTest h2, h2.amtcmp, h2.featureHeading, #productDescription_feature_div > h2.default, #siteDirectory h2, #siteDirectory h2 a {
color: darkslategrey !important;
}
/* - Remove the buy now button on desktop */
/* - Remove the buy now button on desktop - U1 */
#submit\.buy-now{
display: none;
}
/* - Remove the "Pay in x installments free of charge" promp */
/* - Remove the "Pay in x installments free of charge" prompt - U1 */
#issuancePriceblockAmabot_feature_div{
display: none;
}