Hacker Newsnew | past | comments | ask | show | jobs | submitlogin
Show HN: TopLevel – A New Way to JavaScript Your HTML (github.com/kristopolous)
79 points by kristopolous on June 5, 2014 | hide | past | favorite | 48 comments



Reminds me of an example I gave in my book about how you can write valid HTML that executes as JS:

    /*
    <div id="writeHere"></div>
    <script src="#"></script>
    <div>For example here, we have multiple examples of code that execute</div>
    <!--
        */
        writeHere.innerHTML='<p style="font-weight:bolder">Hello World</p>'
        alert("are we JavaScript files or are we HTML?")
        /*
    -->
    */
I saw this once upon a time while debugging some nasty code some publishers used - the whole site was in this style. It was one of the most ingenious things I've seen - the same file, parsed twice, once as HTML and once as JS.


I fail to see why anyone would use that instead of inline <script> tags?

Is it because each tag would then be parsed and run in order, ie you couldn't declare a function at the end of the page that you'd use at the top? It's the only explanation that comes to mind...


IIRC I was investigating a click fraud or impression fraud issue and I came across an entire site written in this fashion.

They were doing something funky with the ad tags that loaded on the page. Clearly they think it will deter people from discovering their naughty misdeeds


You'll end up with the leading '/*' (and trailing) showing in the html though. Not much you can do about it I guess (except probably use a css hack to hide it).

ps I don't envy anybody who has to spend their day working on code that looks like that!


Wow is that ever clever!


This is interesting, could you explain this more in detail?


Not OP but:

1. Page is parsed as HTML, ignoring the JS since it's wrapped in HTML comments.

2. script src="#" loads itself.

3. Page is parsed as JS, ignoring the HTML since it's wrapped in JS comments.


Please do not use this. This will block incremental rendering in a browser. http://www.html5rocks.com/en/tutorials/internals/howbrowsers...

The way TopLevel works, is by getting the complete HTML content, putting it trough a javascript parser, and then rewriting it using document.write.

So this requires all content to be downloaded first, and the toplevel.js to be loaded, before a page can be displayed properly. This breaks all the improvements made in browser, and would significantly slowdown page use.

Also, its completely non standard, and a mis-use of js.

Nice hack however ;-)


Let me respond paragraph-by-paragraph:

---

1. Blocks incremental rendering?

Indeed ... for people not TeeWEE, "incremental rendering" means say a 2MB HTML file will be partially rendered prior to the entire payload being transferred. That is no longer the case here. 100% true. As an aside, I'll think hard about how to overcome this.

---

2. The description of how it works?

Correct. Very succinct. Good Job!

---

3. Significantly slow down a page?

This depends on the page. If it's a small-footprint HTML page which leverages templating, then the base page will be quite small.

If the design previously loaded unneeded dependencies which were only applicable to a subset of users, then this provides a very easy way out without requiring lots of technical knowledge - and probably a good speedup to boot.

As far as actual tests, I've refactored a number of personal projects with this library, and the time to where the spinner stops (if I load the two versions side by side) isn't noticeable through my eyes. I can't honestly tell which one is which.

---

4. A "mis-use of JS"?

It's certainly non-canonical - but I'd argue that many "standard" common practices got their start being just as heretical and then were later replaced by standardized ceremonial ways of doing things.


4. A "mis-use of JS"? It's certainly non-canonical - but I'd argue that many "standard" common practices got their start being just as heretical and then were later replaced by standardized ceremonial ways of doing thing

----------------------------------------

I can't tell you how many hours of time I've wasted on non standard "Standard" things simply because it saved some other guy 20 minutes in time somewhere else. It's a nice hack, but let's leave it at that.... try to improve your resume with other methods.


That was uncalled for.


hey, that hurt my feelings. :-(


Re: 1. Have you considered something like an isomorphic approach to optionally preprocess the HTML on the server side?


You silly creature, I love you!


I think pretty much everything you're saying could be said about Angular, too.


Yo dawg, I heard you liked PHP and Javascript so I made your Javascript work like PHP...


Ok I'll bite ... I made a version that uses "<?" and "?>" as the stanzas --- on a gist:

https://gist.github.com/kristopolous/7d68c3c7cec5f9ac5bc3

Lines 35-37 are the change.

Have fun.


The MDN wiki states that the <plaintext> tag, along with the similar <xmp> and <listing> tags, has been deprecated since the ancient times of HTML 3.2. It also says the support for those tags can disappear suddenly in this HTML5 era.

I know the use of <plaintext> seems to be essential for the implementation, but I'm not sure that it is a reliable way. Are there any alternatives?


The only other way I know to break the interpreter is if you force a bad character encoding of a different bit width.

I have yet to get it working as reliably across the same wide range of browsers.

As far as it disappearing; In order for that to happen one browser group will have to take the first step of intentionally breaking legacy webpages - it seems antithetical to the "render as much as possible" features arm-race nature of the browser world.

Then again, I've been wrong plenty of times before.


Could a textarea tag work too?


not if the document has an existing <textarea> (and thus </textarea>). <plaintext> is rather final ... see here for a demo I just threw together: http://getpostdelete.com/plaintext.html

The HTML interpreter packs up its bags and goes home - you can't "close" a <plaintext> tag if it's existing in a plain HTML page.

However, you can still manipulate it through the DOM.


Yeah I sort of realised that as I said it. Hmm.


For me it's another layer of complexity introduced into the already overly-complex webapp architectures.


From the readme: <img src="logo_<!--= (isMobile() ? "50x50" : "200x200") -->.jpg">

Isn't this a SPOF? If the toplevel.js script fails to load/execute, the <img> will request "logo_.jpg" which does not exist. (The example implies that "logo_50x50.jpg" and "logo_200x200.jpg" exist.)


yes, the whole thing will break if JS is disabled or that script fails to load, but this is hardly a unique failing of TopLevel. Most websites will break under these circumstances these days.


wow, ACT3 syntax from 1999 re-invented. ACT3 was the template / programming script of the austrian national news agency.

instead of JS we used PERL as the inline script language. oh yeah, in the end i wrote a templating language using this templating language until we ditched it for something sane, namely PHP 3 at that time.


I kind of prefer my HTML and CSS to be declarative and not a bunch of complex conditional commands...


I would like to suggest using Knockout for this sort of thing instead. And as I side benefit you get can get reactive observable and a rich HTML binding syntax.

We do this sort of conditional rendering with KO in our application and it works great.

It's quite a mature and focused library.


    "Works Everywhere And Is 0.8 KB."
Everything is gzip/compressed. It is more interesting to know the real file size.


1488 bytes for the minified js and 3773 for the "development" version --- I'll add that ... ok done.


    > The stylesheet above will never load unless the branch is satisfied.
Or if the user has JS turned off.


Nice. What is the impact on performance?


I've only seen it faster than comparable methods.


Interesting, so does it avoid interpreting by using HTML comments as the opening and closing symbols?


By looking the code, the script injects <plaintext> tag while being loaded. So, all the HTML followed by the script element will lose their meanings, just to be rendered as a plain text.

Due to the approach, I guess the start and end tags don't need to be <!-- and -->. It can be anything. The only reason they chose them I guess is that it relieves confusion, though I still think the insertion of the comments in the regular HTML tags looks a bit weird.


I'm trying to incur the smallest impact possible on existing scrapers and give a solution which could still be used to make validating HTML.


I am sure some people will take this seriously and start building apps over this.


minimum 10 years TopLevel experience required


10 years?! Aw shucks! Count me out then. :-(


Job description years are like dog years, nearly there.


First of all good job. Totally different approach, not mainstream way of thinking. Main question: What are real life usecases?


I think you just saved the life of <plaintext>

Cool though. Any performance examples from older/mobile browsers?


nice pitch


Despite the best efforts of millions, XML still sucks as a general purpose programming language.


How's this take? https://github.com/kethinov/teddy

Not exactly a general purpose programming language (as XML really shouldn't be used that way, of course), but I think it takes a lot of the ugly verboseness out of most XML templating systems, including the OP's.

Maybe I should post a "Show HN" thread too. ;)


yes you should. this thing is amazing.


Also, have you heard of ejs? It seems like it has similar design goals to what you're working on. https://github.com/visionmedia/ejs





Consider applying for YC's Fall 2025 batch! Applications are open till Aug 4

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: