Notify on completed compilation #40

Open
opened 2025-03-07 13:17:04 +01:00 by Benjamin_Loison · 20 comments

Usually compile locally but to ensure that when share a document with people on a private instance, hence having unlimited compilation time it seems, then the document is fine. Also as the PDF expires quite quickly it seems but this is maybe due to the specific Overleaf instance I am using.

Related to #38, #31 and Improve_websites_thanks_to_open_source/issues/{540,726,725,727}.

Usually compile locally but to ensure that when share a document with people on a private instance, hence having unlimited compilation time it seems, then the document is fine. Also as the PDF expires quite quickly it seems but this is maybe due to the specific Overleaf instance I am using. Related to #38, #31 and [Improve_websites_thanks_to_open_source/issues/](https://codeberg.org/Benjamin_Loison/Improve_websites_thanks_to_open_source/issues){[540](https://codeberg.org/Benjamin_Loison/Improve_websites_thanks_to_open_source/issues/540),[726](https://codeberg.org/Benjamin_Loison/Improve_websites_thanks_to_open_source/issues/726),[725](https://codeberg.org/Benjamin_Loison/Improve_websites_thanks_to_open_source/issues/725),[727](https://codeberg.org/Benjamin_Loison/Improve_websites_thanks_to_open_source/issues/727)}.
Author
Owner
new Notification("To do list", { body: 'Test' });
Notification { onclick: null, onshow: null, onerror: null, onclose: null, title: "To do list", dir: "auto", lang: "", body: "Test", tag: "", icon: "" }

Source: https://developer.mozilla.org/en-US/docs/Web/API/Notifications_API/Using_the_Notifications_API#creating_a_notification

maybe have to be on another tab to notice it.

Notification.requestPermission().then((result) => {
  console.log(result);
});
Promise { <state>: "pending" }
The Notification permission may only be requested from inside a short running user-generated event handler.
default

Source: https://developer.mozilla.org/en-US/docs/Web/API/Notifications_API/Using_the_Notifications_API#getting_permission

image.png

image.png

image.png

image.png

Can manually at Firefox level provide notification permission?

```javascript new Notification("To do list", { body: 'Test' }); ``` ``` Notification { onclick: null, onshow: null, onerror: null, onclose: null, title: "To do list", dir: "auto", lang: "", body: "Test", tag: "", icon: "" } ``` Source: https://developer.mozilla.org/en-US/docs/Web/API/Notifications_API/Using_the_Notifications_API#creating_a_notification maybe have to be on another tab to notice it. ```javascript Notification.requestPermission().then((result) => { console.log(result); }); ``` ``` Promise { <state>: "pending" } The Notification permission may only be requested from inside a short running user-generated event handler. default ``` Source: https://developer.mozilla.org/en-US/docs/Web/API/Notifications_API/Using_the_Notifications_API#getting_permission ![image.png](/attachments/749ae3ca-508f-4f01-98e2-b2ffca2b48d5) ![image.png](/attachments/ceb8571c-3d38-414e-81eb-a441510dece3) ![image.png](/attachments/2af511d2-c91e-465d-9d3f-b0589a8838c1) ![image.png](/attachments/103b9afa-69f8-497a-9d80-9237d9285d13) Can manually at Firefox level provide notification permission?
Author
Owner

image.png

![image.png](/attachments/3229378a-dba2-41bc-9f59-f90ad138ecde)
134 KiB
Author
Owner

DuckDuckGo search:

  • JavaScript run function when node changed
  • JavaScript run function when innerHTML changed
DuckDuckGo search: - *JavaScript run function when node changed* - *JavaScript run function when innerHTML changed*
Author
Owner
<span class="btn-recompile-label" ng-show="!pdf.compiling">Recompiler</span>
<span class="btn-recompile-label" ng-show="pdf.compiling">Compilation en cours…</span>
```html <span class="btn-recompile-label" ng-show="!pdf.compiling">Recompiler</span> ``` ```html <span class="btn-recompile-label" ng-show="pdf.compiling">Compilation en cours…</span> ```
Author
Owner
JavaScript code:
function getElementByXpath(path) {
  return document.evaluate(path, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
}

var element = getElementByXpath('//span[@class="btn-recompile-label"]');

element.addEventListener('DOMSubtreeModified', myFunction);

function myFunction(e) {
    console.log(element.innerHTML);
}
Adding a listener for DOMSubtreeModified is deprecated and will be removed soon. Instead of a MutationEvent, use MutationObserver. https://developer.mozilla.org/docs/Web/API/MutationObserver

Source: the Stack Overflow answer 47379026

<details> <summary>JavaScript code:</summary> ```javascript function getElementByXpath(path) { return document.evaluate(path, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue; } var element = getElementByXpath('//span[@class="btn-recompile-label"]'); element.addEventListener('DOMSubtreeModified', myFunction); function myFunction(e) { console.log(element.innerHTML); } ``` </details> ``` Adding a listener for DOMSubtreeModified is deprecated and will be removed soon. Instead of a MutationEvent, use MutationObserver. https://developer.mozilla.org/docs/Web/API/MutationObserver ``` Source: [the Stack Overflow answer 47379026](https://stackoverflow.com/a/47379026)
Author
Owner

At random it will be fed with data from an external source (that I do not have control of).

So maybe it does match my needs, as it may be HTML nodes, not just text.

Well the mentioned answer is just about text.

> At random it will be fed with data from an external source (that I do not have control of). So maybe it does match my needs, as it may be HTML nodes, not just text. Well the mentioned answer is just about text.
Author
Owner

Run code snippet works fine.

*Run code snippet* works fine.
Author
Owner

I suspect running my Console code after window.addEventListener('load' can be triggered.

I suspect running my *Console* code after `window.addEventListener('load'` can be triggered.
Author
Owner
JavaScript code:
function getElementByXpath(path) {
  return document.evaluate(path, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
}

window.addEventListener('load', function () {
  var element = getElementByXpath('//span[@class="btn-recompile-label"]');

  var MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver;
  var observer = new MutationObserver(myFunction);
  observer.observe(element, {
	  childList: true
  });

  function myFunction() {
    console.log(element.innerHTML);
  }
});
JavaScript code:
function getElementByXpath(path) {
	return document.evaluate(path, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
}

var element = getElementByXpath('//span[@class="btn-recompile-label"]');

var MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver;
var observer = new MutationObserver(myFunction);
observer.observe(element, {
	childList: true
});

function myFunction() {
	console.log(element.innerHTML);
}

does not work either.

<details> <summary>JavaScript code:</summary> ```javascript function getElementByXpath(path) { return document.evaluate(path, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue; } window.addEventListener('load', function () { var element = getElementByXpath('//span[@class="btn-recompile-label"]'); var MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver; var observer = new MutationObserver(myFunction); observer.observe(element, { childList: true }); function myFunction() { console.log(element.innerHTML); } }); ``` </details> <details> <summary>JavaScript code:</summary> ```javascript function getElementByXpath(path) { return document.evaluate(path, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue; } var element = getElementByXpath('//span[@class="btn-recompile-label"]'); var MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver; var observer = new MutationObserver(myFunction); observer.observe(element, { childList: true }); function myFunction() { console.log(element.innerHTML); } ``` </details> does not work either.
Author
Owner
element.innerHTML 

works fine, maybe it acts as pointer to a copy somehow.

```javascript element.innerHTML ``` works fine, maybe it acts as pointer to a copy somehow.
Author
Owner
JavaScript code:
var element = document.getElementById('recompile');

var MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver;
var observer = new MutationObserver(myFunction);
observer.observe(element, {
	childList: true
});

function myFunction() {
	console.log(element.innerHTML);
}

does not work too.

<details> <summary>JavaScript code:</summary> ```javascript var element = document.getElementById('recompile'); var MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver; var observer = new MutationObserver(myFunction); observer.observe(element, { childList: true }); function myFunction() { console.log(element.innerHTML); } ``` </details> does not work too.
Author
Owner

No iframe seems to blame as I get correctly the node.

No `iframe` seems to blame as I get correctly the node.
Author
Owner
JavaScript code:
function getElementByXpath(path) {
	return document.evaluate(path, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
}

var element = getElementByXpath('//span[@class="btn-recompile-label"]');

var MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver;
var observer = new MutationObserver(myFunction);
observer.observe(element, {
	attributes: true
});

function myFunction() {
	console.log(element.innerHTML);
	console.log(getElementByXpath('//span[@class="btn-recompile-label"]').innerHTML)
}

myFunction is triggered at the beginning and at the end of the compilation but only the latter console.log gives the expected innerHTML.

<details> <summary>JavaScript code:</summary> ```javascript function getElementByXpath(path) { return document.evaluate(path, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue; } var element = getElementByXpath('//span[@class="btn-recompile-label"]'); var MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver; var observer = new MutationObserver(myFunction); observer.observe(element, { attributes: true }); function myFunction() { console.log(element.innerHTML); console.log(getElementByXpath('//span[@class="btn-recompile-label"]').innerHTML) } ``` </details> `myFunction` is triggered at the beginning and at the end of the compilation but only the latter `console.log` gives the expected `innerHTML`.
Author
Owner

Attribute watching may help.

Attribute watching may help.
Author
Owner
const d = new Date();
let time = d.getTime();

gives milliseconds.

```javascript const d = new Date(); let time = d.getTime(); ``` gives milliseconds.
Author
Owner
new Date().toLocaleString()
"25/03/2025, 17:45:58" 

Source: the Stack Overflow answer 30245911

```javascript new Date().toLocaleString() ``` ``` "25/03/2025, 17:45:58" ``` Source: [the Stack Overflow answer 30245911](https://stackoverflow.com/a/30245911)
Author
Owner
JavaScript code:
function getElementByXpath(path)
{
	return document.evaluate(path, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
}

function getRecompileButton()
{
    return getElementByXpath('//span[@class="btn-recompile-label"]');
}

var element = getRecompileButton();

var MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver;
var observer = new MutationObserver(myFunction);
observer.observe(element, {
	attributes: true
});

function getTimestamp()
{
    return new Date().getTime();
}

var lastRecompileTime;

function myFunction()
{
    const currentLabel = getRecompileButton().innerHTML;
	console.log(new Date().toLocaleString() + ': ' + currentLabel);
    switch(currentLabel) {
        case 'Compilation en cours…':
            lastRecompileTime = getTimestamp();
            break;
        case 'Recompiler':
            console.log(`Compilation took ${((getTimestamp() - lastRecompileTime) / 1_000).toFixed(2)} seconds!`)
            break;
        //default:
    }
}
Output:
25/03/2025, 18:29:51: Compilation en cours…
25/03/2025, 18:29:56: Recompiler
Compilation took 5.20 seconds!
25/03/2025, 18:29:59: Compilation en cours…
25/03/2025, 18:30:05: Recompiler
Compilation took 5.33 seconds!

Source: the Stack Overflow answer 15762794

<details> <summary>JavaScript code:</summary> ```javascript function getElementByXpath(path) { return document.evaluate(path, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue; } function getRecompileButton() { return getElementByXpath('//span[@class="btn-recompile-label"]'); } var element = getRecompileButton(); var MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver; var observer = new MutationObserver(myFunction); observer.observe(element, { attributes: true }); function getTimestamp() { return new Date().getTime(); } var lastRecompileTime; function myFunction() { const currentLabel = getRecompileButton().innerHTML; console.log(new Date().toLocaleString() + ': ' + currentLabel); switch(currentLabel) { case 'Compilation en cours…': lastRecompileTime = getTimestamp(); break; case 'Recompiler': console.log(`Compilation took ${((getTimestamp() - lastRecompileTime) / 1_000).toFixed(2)} seconds!`) break; //default: } } ``` </details> <details> <summary>Output:</summary> ``` 25/03/2025, 18:29:51: Compilation en cours… 25/03/2025, 18:29:56: Recompiler Compilation took 5.20 seconds! 25/03/2025, 18:29:59: Compilation en cours… 25/03/2025, 18:30:05: Recompiler Compilation took 5.33 seconds! ``` </details> Source: [the Stack Overflow answer 15762794](https://stackoverflow.com/a/15762794)
Author
Owner
Related to [benjaminloison/kile/issues/24](https://invent.kde.org/benjaminloison/kile/-/issues/24).
Author
Owner
Related to [Improve_websites_thanks_to_open_source/issues/1542](https://codeberg.org/Benjamin_Loison/Improve_websites_thanks_to_open_source/issues/1542).
Author
Owner
Related to [Benjamin-Loison/selenium/issues/16](https://github.com/Benjamin-Loison/selenium/issues/16).
Sign in to join this conversation.
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: Benjamin_Loison/overleaf#40
No description provided.