Is it possible to get a DOM element in GTM custom template? - javascript

Description
So I've read through the GTM Custom template APIs; but I don't find anything regarding getting (e.g.) a div element. I've tried copying document from window using copyFromWindow() or calling document.getElementById through callInWindow(), but both times, I always get this error message when I add document to the permissions:
The value must not start with any key predefined on global scope (i.e. in Window), or any JavaScript keywords.
Question
Is there anyway that it is possible to call a DOM element through custom GTM tags?
My goal is to create a tag that can inject video's in selected div elements. I could do this by creating a custom HTML tag, but I don't want our marketing guy to always go through code. So a tag that asks him for the target ID and video url could make it easier

No. Preventing access to the DOM (and controlling access to the global namespace) is pretty much the point of sandboxed Javascript. Since GTM is not supposed to interfere with the DOM, this should not usually be a problem (well, that's what Google thinks at least).
If you need to learn about some property of a DOM object, you can get this (i.e. the property, not the object itself) via a DOM type variable and pass it in as a data item by creating a field that accept variables.
Simo has a bit about this in his inital write-up on custom templates (you have to scroll down quite a bit). While Google has added a number of APIs since, I doubt that a DOM API is coming up, because that would pretty much defy the purpose of sandboxed Javascript.

Related

Iframe access on elements

I use an Iframe with an external API, which I don't control. My goal is to add Javascript code in my Website, to change the style of a few elements in the Iframe. First I considered using
document.getElementById(iframeId).contentWindow.document.getElementById(elementId);
but I soon recognized that it will not be successful because I am getting security issues. I tested a bit and found out when I inspect the element in the Iframe, which I want to change, I am able to get the element simply by using:
document.getElementById(elementId);
I don't understand. Why does this technique only work when I inspect the correct element first? And is there any way I can use this trick for my normal JS backend?

Does altering the DOM with JavaScript/jQuery mess with accessibility?

I'm trying to figure out if altering the DOM of a website will present any accessibility problems. I am placing all of the jQuery in a $(document).ready() function. Will this cause any accessibility issues with the altered elements?
We don't have access to the theme template HTML files, only CSS and JS files. So for example I'm adding a div into our theme using$('[element name]').before('<div>[div content here]</div>') will this content be as accessible as the rest of the DOM as long as I include all the appropriate aria attributes etc.?
In theory, you shouldn't rely on JavaScript to produce the whole HTML code of your site, it's basically a bad practice.
However, it's exactly how big frameworks like angular and react work.
Given that 99% of browsers support JavaScript, it's in fact no longer a problem nowadays.
The true answer is in fact both yes and no, it depends. It depends on the actual HTML code injected.
The key point is that, you must have the same care with generated code as with the code directly written in HTML by hand, i.e. be careful on headings, form labels, alt texts, ARIA attributes if you need them, etc. all the time and in particular each time you add/remove something in the DOM. Additionally, you must pay attention to where the focus is or might be and a few other things.
It's often overlooked precisely because some people assume that it's anyway not accessible, what isn't true.
In order to be accessible, a site with dynamic contents must be accessible at any moment. If it isn't always the case, then you will lose users in need of accessibility at some point. In practice the loss of accessibility often happens at the most critical moment: checkout or paiement, maybe not because of your fault if the paiement site isn't accessible.
You might even improve accessibility by manipulating the DOM via JavaScript (JS). So no, per se, manipulating the DOM does not pose accessibility issues.
If you cannot control the HTML, and the theme is badly accessible, all you can do to improve that is using JavaScript. Think adding role attributes to generic <div> elements. Also, CSS-only solutions seem appealing, but are often not exposing the appropriate state via ARIA-attributes to assistive technology, which needs to be corrected via JS.
Whether your manipulations produce problems or improve accessibility, therefore depends strongly on your implementation.
Here are some examples.
Adding or Removing Content
When adding content, like in your example, it depends on where that content is added in the document, and at which moment.
If it’s being added on DOM Ready, there should be no issue (One exception might be live regions added after the DOM loaded). But if it’s being added at arbitrary moments, it’s problematic.
The Web Content Accessibility Guidelines (WCAG) refer to this as a Change of Context, which must not happen on focus, on input and on user request
See A change of content is not always a change of context. Changes in content, such as an expanding outline, dynamic menu, or a tab control do not necessarily change the context, unless they also change one of the above (e.g., focus).
If it’s being added after DOM Ready, it should happen on user request, or must be a status message and carry the appropriate role to be announced.
For example, in a Disclosure pattern, the aria-expanded of the trigger indicates that new content will become accessible right after the trigger on pressing it. It might just be added to the DOM, depending on the implementation.
Lazy Loading Content
Another, very valid use case would be content that’s added asynchronously. This is tricky to get right, but basically aria-busy can render this more accessible.

Create an unmodified object in a Firefox addon using WebExtensions

I'm building an addon that works on a page where the canvas element prototype has been modified, this means any new canvas element I create on the page or in the addon with have the same modified state.
Is there a way to get around this? I tried using eval() but it also uses the page "version" of the HTMLCanvasElement.
To get around it in the browser manually I can create an iframe and execute a script inside it that sets a variable on the parent window which I can then of course .call() with the context I want, the problem is that WebExtensions doesn't allow access to variables set by page scripts.
After some more reading I found out that there's a property called wrappedJSObject that allows the content script to access properties set by the page script.
More information: https://developer.mozilla.org/en-US/Add-ons/WebExtensions/Content_scripts#Accessing_page_script_objects_from_content_scripts

Firefox Addon to manipulate DOM without giving the website access to the changes

I write a Mozilla Firefox Addon, that lets me comment websites: When I open a website and click somewhere, the plugin creates a <div> box at this location, where I can enter a comment text. Later, when I open the website again, the plugin automatically puts my previously created comment boxes at the places they where before. (Similar to a comment feature in many PDF readers, etc.)
This leads to a security problem: A website could use an event listener to listen to the creation of new <div> elements and read their content, allowing it to read my private comments.
How can I solve this security issue? Basically, I want a Firefox addon to put private content in a website, while the website should not be able to access this content via JavaScript. (Unless I want it to.)
I could listen to listeners and detach them as soon as the website attaches them - but that does sound like a solid solution.
Is there a security concept in order to make my addon the authority over DOM changes, respectively, to control the access to certain elements?
Alternatively, would it be possible to implement some sort of overlay, which would not be an actual part of the websites DOM but only accessible by the addon?
Similar security problems should occur with other addons. How do they solve it?
If you inject the DOM in a document, the document will always be able to manipulate it, you can't really do much about it. You can either:
1) Don't inject your comment directly in the document, but just a placeholder were there is the first words of the comment, or an image version of the comment (you can generate that with canvas), leave the full ones in your JavaScript Add-on scope, that is not accessible from the page: when you click to edit or add, you can open a panel instead and do the editing there.
2) Inject an iframe, if you have your page remotely in another domain shouldn't be a problem at all, the parent's document can't access to the iframe; but also viceversa: you need to attach content script to your iframe in order to talk with your add-on code, and then you can use your add-on code to send and receive messages from both iframe and parent's document.
If you use a local resource:// document, I'm afraid you need a terrible workaround instead, and you need to use sandbox policies to avoid that the parent's document can communicate with the iframe itself. See my reply here: Firefox Addon SDK: Loading addon file into iframe
3) Use CSS: you can apply a CSS to a document via contentStyle and contentStyleFile in page-mods. The CSS attached in this way can't be inspected by the document itself, and you could use content to add your text to the page, without actually adding DOM that can be inspected. So, your style for instance could be:
span#comment-12::after{
content: 'Hello World';
}
Where the DOM you add could be:
<div><span id='comment-12'></span></div>
If the page tries to inspect the content of the span, it will get an empty text node; and because from the page itself the stylesheet added in this way cannot be inspected, they cannot the styles rules to get the text.
Not sure if there are alternatives, those are the solutions that pop to my mind.
Add-ons that do similar things implement some combination of a whitelist / blacklist feature where the add-on user either specifies which sites they want the action to happen on, or a range of sites they don't want it to happen on. As an add-on author, you would create this and perhaps provide a sensible default configuration. Adblock Plus does something similar.
Create an iframe and bind all your events to the new DOM. By giving it a different domain to the website, you will prevent them from listening in to events and changes.
Addons can use use the anonymous content API used by the devtools to create its node highlighter overlays.
Although the operations supported on anonymous content are fairly limited, so it may or may not be sufficient for your use-case.

jquery - how do i access those arrays and variables in the dom?

Im using firebug to debug jquery and in the dom tab i can see all the vars and arrays in there.
How do I access the different arrays and vars in the dom?
Cheers
Ke
I cannot access these object items, even though firefox lists them, i have sitems in the top level of the dom, i also have sitems within the parent variable.
a lot of head scratching happening here, would be grateful for any help :)
Looks like you want to access a user defined property, since these are not properties of the DOM ( Firebug Wiki DOM panel page. ), I don't think you can access them directly through your page, but you can access them through the Firebug console.
Simply type the name of the property into the command line of the Console... the part after >>> on the very bottom.
In your case you would type something like: sitems[0] and hit enter.
To access properties of the DOM... take a look at the DOM exploration page for Firebug.
To see how to access properties, functions, or constants of the DOM, check what you're interested in in the DOM tab.
Then you can "follow the bread crumbs" to access properties directly. Global properties are attached to window, so you don't need to include window:
Make sure to right click on things and explore the context menu, especially if you start looking at functions.
If it's an array you should access it as an array by referencing the index in the Array you are trying to access.
alert(sitems[1]);
If it's an object you can reference by using the "key" for the property or method of the object you are trying to access:
alert(sitems["keyName"]);
Likewise some of the stuff you'll see in the DOM tab are actually references to methods and objects within the DOM, so if you're going to call them or reference them you need to do so based on their type, or you may even need to provide arguments to them in order to get a response.
It's giving 'undefined' because you can't output the contents of an Array just by calling its name.

Categories

Resources