Access surrounding HTML elements through JavaScript with no context - javascript

What I want is to be able to work on context-free HTML elements surrounding 'entry points' (like <script> tags or events) using JavaScript. I have some tight restrictions on what I can do.
Summary
I have multiple user-generated blocks of HTML which need to be processed on their own, as they load.
The content of these blocks can contain similar blocks, with similar behaviour.
The content will also need to be duplicated once, possibly restarting execution of the scripts mentioned in 2.
These blocks are generated from static templates and cannot (initially) contain unique identifying data, like IDs or random attribute values.
These blocks can also be generated through AJAX, which is out of my control. They will need to take care of themselves as they appear, without relying on any order of execution.
Background
This is for a forum software, where certain BBCode tags, say [tag]content[/tag] are replaced with fixed HTML. I have no access to any server-side scripting, so the replacements are context-independent, i.e. always the same.
For example, [tag]{content}[/tag] would turn into something like:
<span ...>
...
{content}
...
<!-- script entry point -->
</span>
I need to do some client-side processing around the time when the data is loaded.
I cannot change the requirements of the problem. The end product is code for generating tabs, like:
[tabspace]
[tab]content 1[/tab]
[tab]
content 2, and
nested tabs:
[tabspace]...[/tabspace]
[/tab]
[/tabspace]
The content that is output by the script consists in the "tab buttons" themselves, which would link to their respective content.
Restrictions
I cannot use IDs. Everything must be or start as a context-free replacement of the template.
[tag]s can be nested.
The script needs to duplicate some of the content, parts of which can be similar scripts and so on. This messes up scripts which are already running on the outer pairs of tags. I have a bottom-up solution to solve this, but it relies on starting scripts at any depth without worrying about similar surroundings. (another way to phrase it)
These tags can be loaded dynamically in any post on the page, at any time, using AJAX.
There can be scripts at any point in the template, to make the problem easier.
What I tried
Using JS to dynamically output a <span id='something random'></span> as it loads, search for the given ID and use its location to find the surrounding elements. It doesn't work when I load pages dynamically and when tags are nested.
Give a class to the surrounding element and find the last element of its kind. This doesn't work because we may have updates in the middle of the page, after it's loaded.
Solutions which I'd rather avoid
Using <img src='bogus' onerror='script entry point'/>, I can run a script and access surrounding tags using this. But I'd rather not use broken links and errors to solve a simple and pertinent problem.

Related

Handing multiple email HTMLs in a single page

We are implementing an email support application. As in any other support application, the customer can send multiple emails in a thread or chain. This chain can also include replies from the agent, who is working on resolving the case. The HTML display, in this case, is structured as below,
<html>
<head>
</head>
<body>
<div>
EMAIL 1 - This has it's entire HTML content. Including Body css etc etc.
</div>
<div>
EMAIL 2 - This has it's entire HTML content. Including Body css etc etc.
</div>
<div>
</div>
</body>
</html>
The problem we are facing is these emails come with their own HTML content. This is causing in many cases conflict with our HTML structure or CSS or both. Resulting in the page to break in structure or for the CSS to get miss represented.
We tried putting these individual mails in an iframe, but that's causing the page-load to become very slow or unresponsive when there are multiple emails in a thread.
<iframe id="html_content" style="overflow:hidden;" scrolling="no" frameborder="0" width="100%" onload="this.height=this.contentWindow.document.body.offsetHeight+20 + 'px';" srcdoc="<div>{{htmlContent}}</div>"></iframe>
Any suggestions on how this could be handled best and reduce conflict with our page css or html structure would help.
You need to do what Gmail etc. do and modify the code before it's inserted into the page.
You can reverse-engineer their emails by looking at the output code from within a robust email client. (See https://webapps.stackexchange.com/questions/33926/can-i-view-the-html-source-of-an-email-sent-to-my-gmail-address for Gmail source code.)
To avoid CSS clashes, you will essentially need to prefix all incoming CSS classes.
To avoid HTML clashes, you'll need to disallow certain properties (or only allow some). For example, you won't want fixed positioning. Absolute positioning may require your wrapping div to be positioned relatively.
You need to change the <body> tags to a <div>.
You need to remove the <html> tag, and <meta> tags, after you've interpreted them. I.e. some <meta> tags contain instructions like "this email accepts dark mode", or, "this email only accepts light mode" - and you'll need to interpret accordingly, if you think you need to do anything with them. You might be able to safely ignore them (remove them) for a first version.
You may want to insert lazy loading functioning so that only certain content gets loaded at a time - particularly images and other assets (although typically it is expected that external stylesheets get stripped, since you can't ensure they won't interfere).
For security and non-interference, you need to remove <script> tags.
For mobiles, I've noticed that there is some sort of detection for responsiveness, and if the email is not responsive, the email software will add something like a transform: scale (0.xx) to the outer wrapper(s) so that it fits. Deal with that how you like.

PHP - safely allow users to save html

I'm writting a website that allows users to paste in html for their blogs.
The html they paste in will then get saved to a file and this is what will be read and changed when the user makes changes. The file will almost be like a complete web page so it will have all your normal tags; head, body, div's, etc. etc.
This means it should allow almost all html and css tags apart from anything that could cause a security breach. So it essentially needs to strip php tags, certain style tags, and html/javascript script tags.
I looked into the strip_tags function but I'd rather not use that because:
a) it removes html comments which I'd rather keep and
b) it would be a lot of working specifying all the tags that it needs to ignore, considering I want it to ignore vastly more tags than I want it to strip.
My guess is that this is something regex-esc using preg_replace?
I'd like to add; I'm newly aware of XSS attacks through CSS too so any ideas/thoughts on how I could block certain css style tags out would be wonderful :)
Any ideas on what I could do?

if some parts of the html are repeated in several documents, is it more efficient to load it in the js?

For example, say you have an information box that will be repeated in every single page. if i have this in the HTML, then every time i change it, ill have to change it in every single HTML file.
But if i load it in the javascript (as in the whole thing), then I'll only need to change the javascript. For example,
$("body").append('<div id="infobox">*whatever i need*</div>')
is this a better way or does it create more complications?
or are there more efficient ways to do this?
In short, no. You're on a slippery path there…
It might be more efficient for the person maintaining the page but you should really be doing this on the server-side as mohkhan suggested e.g. through a CMS or pre-processing if you're site is completely static. I assume that on your site, there isn't just an info box that's repeated — what about the navigational elements, the banner etc.?
There's nothing wrong with loading elements through JavaScript (e.g. to show counters, data, etc.) but you shouldn't be doing it for core content. Remember too that you shouldn't assume that everyone will have JavaScript enabled.

HTML Template (Custom) Tag

I understand that using custom html tags is improper for a variety of reasons, but I wanted to run a specific situation by you that might warrant a custom html tag and hopefully get told otherwise or possibly a better way of achieving my goal.
Throughout my code I have what I term as templates that are made up of a div tag with a template and a hidden class attached to it. This is not visible on the screen, but basically these "template" tags contains html that I use in Javascript to create a variety of different items. I do this so that I can style my templates in html rather than have to worry about mixing CSS in with my Javascript.
<!-- TEMPLATE -->
<div class="template hidden">
<span>Random Container</span>
Random Button
</div>
In javascript I would do something like
var template = document.getElementById("template");
var clone = template.cloneNode(true);
clone.removeClass("template hidden");
I would rather be able to do something like this
<template class="hidden">
<span>Random Container</span>
Random Button
</template>
So that if I have multiple templates in a single div I can grab them all rather than having to give them unique class names. Of course my reasoning for needing an implementation goes a lot deeper than this, but its not necessary to waste your time with the details. Let's just say that it will help clean up my Javascript ALOT.
Because the custom template tag is hidden and really is nothing more than a container that is convenient to call within javascript with document.getElementsByTagName("template"); Is this ok to do? I would probably prefix the tag with a custom name in case template ever gets implemented into html.
Modern browsers generally “support” custom tags in the sense of parsing them and constructing DOM nodes, so that the elements can be styled and processed in scripting.
The main problem is IE prior to IE 9, but it can be handled using document.createElement('...') once for each custom tag name.
Another problem is that validators will report the tags as errors, and if there are loads of such errors, you might not notice some real errors in markup. In principle you can create your own DTD to deal with this (I have an HTML DTD generator under construction, but it is trickier than I expected...).
With these reservations, use custom tags if they essentially simplify your job as compared with using classes.
Why not use one of HTML5's data attributes? They are for storing private data or custom info.
For your case, you could add data-type="template" or data-name="template" and then search and remove based on that. One simple function just like you would write to remove your <template> tag, but without breaking rules.
So, using your example, <div data-type="template" class="hidden"></div>

How to implement an Enterprise-grade JavaScript "framework" for web designers?

I have been tasked with improving the current mess that is our JavaScript "strategy"; we're an online shopping company and my boss has given me time to do this properly. He is very keen on keepin this modular and increase the reusability of the components.
Our HTML is being rendered with JSP and we have lots of custom tags writing out, for example, information about products without the web designers needing to worry about it.
Now, we want to do similar things with JavaScript. The web designers should be given a set of custom tags, like, say,
<foo:draggable>
... some HTML here ...
</foo:draggable>
that will wrap the HTML in a <div> with a drag bar at the top and a close button.
My idea is to mark the div with a unique namespaced CSS class name, like foo_draggable, and then put all my functions in a single JS file. That JS file then sees if there are elements with the CSS class foo_draggable in the DOM and if it finds any it will attach the required event handlers.
However, I am worried about scaling problems, and wondering whether it is a good idea to have lots of selector queries running when they quite often aren't going to be used.
The first alternative would be to initiate each draggable item explicitly but that would mean putting <script> tags all over the place. The second approach would be to not put all UI function in one file but rather just download the ones I need, but that would mean lots more HTTP requests and slower page load speed.
Has anyone got experience with this?
What about having two classnames?
<div class='foo fooDragable'></div>
<div class='foo fooSortable'></div>
You add the class 'foo' to all your elements that require javascript modification.
Your javascript has to check the dom only once for foo.
var $foo = $('.foo');
Afterwards you can search within this array which should be way smaller than the complete dom.
var $dragAble = $foo.filter('.fooDragable');
Have you considered or taken a look to JSF? I know it's a major change if you aren't using JSF yet. But there are lot of ready-to-use JSF component libaries with an ajaxical sauce, for example RichFaces, IceFaces, PrimeFaces, etc. It's almost a waste of time to create components/tags for it yourself.
Alternatively you can replace all Javascripts to use the great jQuery JS framework.
Depending on how many separate components you have, the extra overhead of running the selectors might not be a big deal. You can initialize all the components just the once, when the page is loaded. Anything that's not present on the page simply won't get initialized, and will incur no further overhead. In most JavaScript frameworks, selecting by classname (or tag name) is pretty fast. It's only the complex selectors, which aren't natively supported by the browser, that are slow.
If you have a few commonly used components, and then a set of less commonly used ones, it may be worth splitting those up. Keep the commonly used components in a single JavaScript file (minified, served with compression and aggressive caching), and load that in every page, regardless of whether it's needed or not. Caching will ensure it's only downloaded once, and it'll only be one small HTTP request. For the less common components, keep them in separate files (ideally, one per component), and add a script tag on pages that use them.
I'm not entirely familiar with how JSP works, but it might be possible to do this automatically - if a tag is included in the document, add a script tag for foo_widget.js in the document header, or something like that.

Categories

Resources