Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Custom DOM library support on Node.js (e.g. JSDOM) #158

Closed
saschanaz opened this issue Sep 28, 2019 · 3 comments · Fixed by #165
Closed

Custom DOM library support on Node.js (e.g. JSDOM) #158

saschanaz opened this issue Sep 28, 2019 · 3 comments · Fixed by #165

Comments

@saschanaz
Copy link
Contributor

Hi, nanohtml maintainers:

I'm a maintainer of ReSpec and currently working on porting our string template HTML code to make it work on Node.js without big changes.

We need a way to generate DOM tree instead of a string from inline HTML, because our code currently heavily relies on DOM APIs. I wonder we could do something like this:

// On Node.js
const html = require("nanohtml");
const document = /** get a Document object from JSDOM */;
const anchor = html(document)`
  <a>Yay, DOM in Node.js!</a>
`;
anchor.href = "https://example.com";

What do you think? Would this also benefit other nanohtml users?

@goto-bus-stop
Copy link
Member

goto-bus-stop commented Sep 28, 2019

There could be a new nanohtml/dom API that does that, but you can also do this today:

var html = require('nanohtml/lib/browser')

global.document = jsdomDocument
var el = html`
  <h1>uses jsdom</h1>
`

or:

function html (document) {
  var inner = require('nanohtml/lib/browser')
  return function (strings, ...expressions) {
    global.document = document
    var result
    try {
      return inner(strings, ...expressions)
    } finally {
      delete global.document
    }
  }
}

@saschanaz
Copy link
Contributor Author

saschanaz commented Sep 28, 2019

The maintainer of hyperhtml suggested same thing but I don't want to pollute global scope. (And I hope there be no hack modifying and de-modifying global scope.)

@goto-bus-stop
Copy link
Member

I wouldn't be opposed to a dependency injection like API like you suggest. I think to implement it, the simplest way is to:

  1. move all of lib/browser.js to a new lib/dom.js file
  2. wrap lib/dom.js in a big closure that takes a document argument
  3. update lib/browser.js to do module.exports = require('./dom')(document)
  4. add a new /dom.js module that exports ./lib/dom.js (similar to how we have /raw.js already)
  5. add some tests using jsdom or whatever (that would only run on node.js versions still supported by jsdom)

then it could be released as a minor version.

I don't really wanna do it myself 🙈 but would review a PR, whether it takes the above approach or a different one!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants