Skip to content

Execute Custom JS prior to TTS queue extraction in core.js #17

Description

@snthsh2

Describe your suggested feature

Problem Statement

LNReader provides an excellent feature allowing users to inject custom user JavaScript via 'Settings → Reader → Advanced' to alter the layout or clean text. However, when using the Advanced TTS engine, text-scraping configurations inside the background service grab the elements via window.tts.getTextNodes() before the custom user scripts finish executing asynchronously or observing DOM changes.

As a result, aggressive anti-scraper watermarks (such as lookalike text blocks, unicode swaps, and sentence spaces corrupted by strings like u2014 on platforms like Novelight) bypass our custom cleaning scripts and are read out loud by the native Android TTS engine.

Describe the solution you'd like

Instead of hardcoding site-specific cleaning regex into the app repository, I would like to request a structural timing change to how custom user scripts interact with the TTS cycle.

If the WebView core script (core.js) hooks and runs user-defined Custom JS synchronously right at the beginning of the window.tts.getTextNodes execution block, users will have the flexibility to scrub, manipulate, or filter text elements locally before they ever touch the Android TTS background queue.

This keeps the repository lightweight and gives power-users an immediate way to handle complex anti-bot sentence formatting dynamically.

Other details

Implementation Idea / Example

Inside android/app/src/main/assets/js/core.js, we can ensure any user-injected functions or a designated global cleaning hook are triggered right before the text serialization array is built:

window.tts = {
    getTextNodes: function() {
        // 1. Invoke custom reader JS/cleanup configurations first if present
        if (typeof window.executeCustomUserReaderJS === 'function') {
            window.executeCustomUserReaderJS();
        }
        
        // 2. Original array parsing and extraction happens here...
        let paragraphs = [];
        // ...
        return paragraphs;
    }
};

This tiny execution hook gives us a permanent bridge to clean up layout text and keep background audio completely pristine without forcing the core dev team to maintain scraper-fighting scripts!

Acknowledgements

  • I have searched the existing issues and this is a new ticket, NOT a duplicate or related to another open or closed issue.
  • I have written a short but informative title.
  • If this is an issue with a source, I should be opening an issue in the sources repository.
  • I have updated the app to version 2.0.2.
  • I will fill out all of the requested information in this form.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions