Multipurpose browser extension to improve the Desire-To-Learn (D2L) online learning platform.
- Preview files in various supported formats from submissions within a new tab without a download.
- Calendar integrated into the homepage (ensure first class is NOT closed).
- MORE SOON!
- Navigate to latest release here
- Download
source_code.zip
- Unzip the
source_code.zip
- Navigate to
chrome://extensions
- Click the
Developer Mode
toggle on (top right)
- Click
Load Unpacked
(top left)
- Find the directory of the extracted extension, select, and enjoy
Notice: typescript transpiler required
To install, ensure a package manager such as node.js is present on the machine.
npm install -g typescript
npm init -y
npm install typescript --save-dev
Finally, to compile run tsc
, or if you prefer a live compiler tsc -w
For additional information on how to access shadowRoot elements with querySelectors, refer to
|
async function waitForElement(selector) { |
|
while (document.querySelector(selector) === null) { |
|
await new Promise(resolve => requestAnimationFrame(resolve)); |
|
} |
|
console.log(document.querySelector(selector)) |
|
return document.querySelector(selector); |
|
} |
|
|
|
async function waitForShadowElement(parent, selector) { |
|
while (parent.shadowRoot === null || parent.shadowRoot.querySelector(selector) === null) { |
|
await new Promise(resolve => requestAnimationFrame(resolve)); |
|
} |
|
return parent.shadowRoot.querySelector(selector); |
|
} |
|
|
|
async function waitForChildElement(parent, selector) { |
|
while (parent.querySelector(selector) === null) { |
|
await new Promise(resolve => requestAnimationFrame(resolve)); |
|
} |
|
return parent.querySelector(selector); |
|
} |
|
|
|
async function waitForAnyShadowElement(parent, selectors, timeout = 30000) { |
|
let startTime = Date.now(); |
|
while (Date.now() - startTime < timeout) { |
|
for (let selector of selectors) { |
|
if (parent.shadowRoot && parent.shadowRoot.querySelector(selector)) { |
|
return parent.shadowRoot.querySelector(selector); |
|
} |
|
} |
|
await new Promise(resolve => setTimeout(resolve, 100)); // Check every 100ms |
|
} |
|
return null; // Timeout reached without finding elements |
|
} |
|
|
|
|
|
|
|
//Calender Button: NOTE (FIRST CLASS IS THE ONE THAT IS USED, ENSURE IT IS NOT CLOSED.) |
|
(async () => { |
|
let element = await waitForElement('.d2l-body.d2l-typography.vui-typography.d2l-tiles-container.daylight .d2l-page-main.d2l-max-width.d2l-min-width .d2l-page-main-padding .d2l-homepage .homepage-container .homepage-row .homepage-col-8 .d2l-widget.d2l-tile[role="region"]'); |
|
element = element.querySelector('d2l-expand-collapse-content'); |
|
element = element.querySelector('div.d2l-widget-content-padding d2l-my-courses'); |
|
console.log(element) |
|
element = await waitForShadowElement(element, 'd2l-my-courses-container'); |
|
element = await waitForShadowElement(element, 'd2l-tabs d2l-tab-panel'); |