๐ Sigarra Tools | An extension that makes the information system of the University of Porto slightly better.
Sigarra on Steroids: export calendar events (timetables, events, book renewal, payments, ...); infinite scroll; export, filter and sort data-tables; statistical analysis on grades; library book renewal; configurable behaviour and more. SigToCa's heir
Most features are customizable and can be turned off in the options page.
Any Sigarra data-table is now:
SigTools exports to iCalendar .ics format which means most applications handle it pretty well, namely
It was developed to be as non-intrusive as possible, requires minimal permissions, only executes processes when it needs to, and all the scripts are loaded after the pages are ready so as to minimize any interface performance impact!
You can contribute by:
npm install
npm run chrome-watch
or npm run firefox-watch
or npm run opera-watch
during development
build/
foldernpm run build
when ready for final tests followed by npm run zip
to create all the zip files (this step is optional in PRs)/build
or /dist
)my-slack-workspaces/build/chrome
or (my-slack-workspaces/build/opera
)my-slack-workspaces/build/firefox/manifest.json
Run npm run build
+ npm run zip
to create a zipped, production-ready extension for each browser (atm there seems to be a strange issue with npm run dist
).
extractors
for all the scripts that extract information from a page and act accordinglylib
for external scriptsscripts
for the JS scripts that are atomic or that are used for an html
pageutils
for functions that are reused among the extractors
and other scriptsIn the manifest.json file, in the content_scripts
section, there is an initial match to load all the global scripts and then, for each page, each extractor is loaded.
class NewExtractor extends Extractor{
constructor() {
super();
...
this.ready(); // this will trigger init and then attachIfPossible
}
//must implement: structure, attachIfPossible
structure() { return {...} }
attachIfPossible() {...}
...
}
// All the functions that are used by this script but do not
// belong to the class definition should follow the above line
...
By default, each extractor that inherits from Extractor
already has the storage.boolean.apply
and storage.text.exclude_urls_csv
options.
The structure()
method should return an object that describes the extractor, following this stub:
{
extractor: "the name of the extractor", // must be unique among extractors
description: "a simple description of what it does",
parameters: [{//a list of the parameters that can be used ny users
name: "name of the parameter",
description: "either describe or exemplify"
}
//... other parameters
],
storage: { // the variables to save for this extractor (in the local storage)
text: [ //variables that should be displayed and edited in <input type="text">
{
name: "the name of the variable, eg: title",
default: "The default value, eg: [${acronym}] - ${room.name}"
}
],
textarea: [ //variables that should be displayed and edited in <textarea></textarea>
{
name: "description",
default: "another description - can have <strong>HTML</strong> inside"
}
],
boolean: [ //variables that should be displayed and edited in <input type="checkbox">
{
name: "isHTML",
default: true
}
]
}
}
After developing a new extractor, it should be added to the options.html page as <script src="js/extractors/NAME.js"></script>
next to the ones already there.
Testing a browser extension is hard. Nonetheless, we try. Tests are located in the test folder and we use mocha and chai along with some improvised magic.
To run tests open the tests.html file on the browser (we advise Live Server for VSCode), this was the only way as chrome extensions cannot be fully developed as ES6 modules, as of now. This system works fairly well.
To create a new test, check the previous ones. If you need to load html as the current jquery context (you will for every test with jquery selectors) you can do:
describe('what the test is about', function() {
it('should return some results', function(done) {
updatejQueryContext("new_context.html").then(() => {
// your tests
done()
}).catch(done)
})
})
or, for the context to be global:
describe('what the test is about', function() {
before(() => {
return new Promise((resolve)=>{
updatejQueryContext("new_context.html").then(resolve)
})
})
it('should return some results', function(done) {
// your tests
})
})
describe(...
After developing a new test, it should be added to the options.html page as <script src="test/extractors/NAME.js"></script>
next to the ones already there.
A thanks to... ics.js | FileSaver.js | Blob.js | mustache | chart.js | math.js for saving us a lot of time!
Credits to Paomedia for the flat calendar icon!
Credits to Icons8 for services icons such as Office 365, Outlook, Google and Yahoo.
exclude_urls_csv
bug that disabled all extractorsdocument
mocking in unit tests #90
mailto
links near all profiles find within current page.ics
#113
.ics
and 'one-click'