Giter VIP home page Giter VIP logo

vhtml's Introduction

vhtml

NPM travis-ci

Render JSX/Hyperscript to HTML strings, without VDOM

Need to use HTML strings (angular?) but want to use JSX? vhtml's got your back.

Building components? do yourself a favor and use Preact

JSFiddle Demo


Installation

Via npm:

npm install --save vhtml


Usage

// import the library:
import h from 'vhtml';

// tell babel to transpile JSX to h() calls:
/** @jsx h */

// now render JSX to an HTML string!
let items = ['one', 'two', 'three'];

document.body.innerHTML = (
  <div class="foo">
    <h1>Hi!</h1>
    <p>Here is a list of {items.length} items:</p>
    <ul>
      { items.map( item => (
        <li>{ item }</li>
      )) }
    </ul>
  </div>
);

New: "Sortof" Components!

vhtml intentionally does not transform JSX to a Virtual DOM, instead serializing it directly to HTML. However, it's still possible to make use of basic Pure Functional Components as a sort of "template partial".

When vhtml is given a Function as the JSX tag name, it will invoke that function and pass it { children, ...props }. This is the same signature as a Pure Functional Component in react/preact, except children is an Array of already-serialized HTML strings.

This actually means it's possible to build compositional template modifiers with these simple Components, or even higher-order components.

Here's a more complex version of the previous example that uses a component to encapsulate iteration items:

let items = ['one', 'two'];

const Item = ({ item, index, children }) => (
  <li id={index}>
    <h4>{item}</h4>
    {children}
  </li>
);

console.log(
  <div class="foo">
    <h1>Hi!</h1>
    <ul>
      { items.map( (item, index) => (
        <Item {...{ item, index }}>
          This is item {item}!
        </Item>
      )) }
    </ul>
  </div>
);

The above outputs the following HTML:

<div class="foo">
  <h1>Hi!</h1>
  <ul>
    <li id="0">
      <h4>one</h4>This is item one!
    </li>
    <li id="1">
      <h4>two</h4>This is item two!
    </li>
  </ul>
</div>

vhtml's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

vhtml's Issues

Possible injection because of sanitize cache

Basically it's possible to inject dirty html:

const striked = '<strike>test</strike>';

console.log(<div>{striked}</div>);
console.log(<div><strike>test</strike></div>);
console.log(<div>{striked}</div>);

This is the output:

<div>&lt;strike&gt;test&lt;/strike&gt;</div>
<div><strike>test</strike></div>
<div><strike>test</strike></div>

Expected output:

<div>&lt;strike&gt;test&lt;/strike&gt;</div>
<div><strike>test</strike></div>
<div>&lt;strike&gt;test&lt;/strike&gt;</div>

After rendering <div><strike>test</strike></div>, it caches <strike>test</strike> and doesn't sanitize it anymore. It can be seen live here as well. Just because something was rendered before, it shouldn't mean that it's sanitized.

unable to use vhtml in vite

I tried to configure vhtml in vite's vanilla javascript template but I'm unable to implement it. Please guide me on how to configure it.

main.js
------

/** @jsx vhtml */
import { Counter } from "./src/counter";

document.body.innerHTML = (
  <main>
   <Counter/>
  </main>
);
/** @jsx vhtml */

export function Counter() {
  let count = 0;
  return (
    <section>
      <h1>Click button</h1>
      <button onClick={() => count++}>Click me</button>
    </section>
  );
}
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <link rel="icon" type="image/svg+xml" href="/vite.svg" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Vite App</title>
  </head>
  <body>
    <div id="app"></div>
    <script type="module" src="./main.jsx"></script>
  </body>
</html>

image

Rendering HTML entities

vhtml renders &ldquo; as &amp;ldquo;, which causes the source string to appear in the output.

It would be helpful if entities in the "quasis" of the template string were left alone, and interpolated string values were escaped:

// Source
const copyright = '&copy; 2021';
return html`<div>&ldquo;${copyright}&rdquo;</div>`;

// Rendered output
<div>&ldquo;&amp;copy;2021&rdquo;</div>

Publish new version?

Is it possible to publish a new version?

A few enhancements have been merged recently, but they're difficult to use via npm.

Add support for children elements

Hi! Great work :)
I was wondering if there was a way for adding children elements to components like one would do in React. Some like this:

const Child = () => (
	<div>Child here!</div>
);


const Elem = (items) => (
	<div class="foo">
		<h1>Hi!</h1>
    <Child />
		<p>Here is a list of {items.length} items:</p>
		<ul>
			{ items.map( item => (
				<li>{ item }</li>
			)) }
		</ul>
	</div>
)

const list = ['one', 'two', 'three'];
document.body.innerHTML = Elem(list);

I found that if I add them like this it works fine but is not as clear as the previous version.

const Child = () => (
	<div>Child here!</div>
);


const Elem = (items) => (
	<div class="foo">
		<h1>Hi!</h1>
    { Child() }
		<p>Here is a list of {items.length} items:</p>
		<ul>
			{ items.map( item => (
				<li>{ item }</li>
			)) }
		</ul>
	</div>
)

What do you think of adding something like this? If you like the idea I could work on it and submit a PR.
Thanks again!

Why does this library exist?

Why does this library exist when you can just use template strings?

function myComponent(props) {
  return `<div>${props.name}</div>`
}

render nothing if the param is the number zero

In react, the number zero will be rendered directly, rather than taken as false or null.

let items = ['one', 'two', 'three']; document.body.innerHTML = ( <div class="foo"> <h1>Hi!</h1> <p>Here is a list of {items.length} items:</p> <ul> { items.map( item => ( <li>{ 1 }</li> )) } </ul> </div> );

Maintenance

Hey everyone

Since we use this project and the maintainer did not respond for a while I went ahead and forked this project here. (npm)
I've incorporated various fixes/ideas from issues and pull requests to vhtml while rewriting the code for readability, adding more tests and a benchmark. I also tried to improve the documentation according to some questions/concerns that have been raised here on vhtml.

Feel free to send pull requests or create issues over there, and we will do our best to respond to them.

Keep in mind that the fork intentionally makes a few breaking changes, which is also why I bumped the major version number.

Safe HTML in data

Is there any way to render safe html in data, kind of like dangerouslySetInnerHTML in React? I'm talking about having some data like:

{
  firstName: 'John',
  lastName: '<b>Doe</b>'
}

How to render html comment

Is it possible to render HTML comments, I am using this to render server side templates, and it would be useful to print out html comments so it helps with debugging and getting meta information

Thoughts on TypeScript support?

First of all, great project. The simplicity is beautiful.

I am curious on your thoughts on adding typings in some form to this repo from a maintainer perspective. I am happy to do the work here, but don't want to create a maintenance burden.

In order of personal preference:

  1. Rewrite/convert the package with TypeScript, using your microbundle package?
  2. Add .d.ts files to the current implementation?
  3. Create a definitely typed package for @types/vhtml?

JSX pragma, flow config and vhtml

Hi,

I tried vhtml and it looks fine.

However, to integrate it in my stack I need to make it properly working with .flowconfig

  • what's the pragma @jsx syntax to use with vhtml?
  • is there a way to alter .flowconfig to 'prepend 'automatically this @jsx tag to all files ?

Currently I'm using : rollup + buble + flow + vhtml

Thanks for help.

Doesn't render 0

JSX should only ignore boolean, null and undefined.

But it doesn't render 0:

Modified example of numbers:

let items = Array.from({ length: 10 }, (_, i) => i);

The first item is not rendered.

https://jsfiddle.net/ts0Lhcfq/

How do I use this with TypeScript?

I can figure out the:

{
  "compilerOptions": {
    "jsx": "react",
    "jsxFactory": "h",
  },
}

But I can't figure out how to get the typings going for h and things like children,

Specifically the error I'm getting on any JSX element is:

JSX element implicitly has type 'any' because no interface 'JSX.IntrinsicElements' exists.ts(7026)

Fragment / jsxFragment support

Hi, this is a cool project, thanks so much.

I am using Typescript to compile the JSX, with this tsconfig.json:

    "jsx": "react",
    "jsxFactory": "h",

Most code is converted properly, except when using a fragment:

const foo = <>
   <tr><td>row 1</td></td>
   <tr><td>row 2</td></td>
</>

this warning from Typescript is given:

The 'jsxFragmentFactory' compiler option must be provided to use JSX fragments with the 'jsxFactory' compiler option.

I tried "jsxFragmentFactory": "Fragment", in tsconfig.json but of course no such Fragment is known nor exported from the vhtml import.

  • Is it possible to support JSX fragments in VHTML?
  • Is there any other way of storing multiple <tr> siblings as per the above example?

New release?

We've spiking this module as part a lightweight framework-independent component setup we have going on. At present we are bundling a custom vhtml module with our code (simply lifted from this repo) because we need the attribute mappings in the master branch that not current available in the latest NPM package.

Is this project no longer maintained (if so feel free to move me along! Or do you need a maintainer? I'm aware you must be incredibly busy, we'd be happy to help if we can) or is a new minor release possible to get the added goodness out there?

SSR Memory leak

I recently added this package in our project and I was told it's causing memory leak in our prod env.

After reading the code, it seems like it's the sanitized cache that's causing the problem.

sanitized[s] = true;

Every generated html string(s) would be stored in this cache, and it seems to have caused our server run out of memory and keeps restarting.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.