Expose specific element in ShadowDom to external JS using document.getElementById - web-component

I have a v0/Polymer 1 web component that I am upgrading to v1/Polymer 2. This web component dynamically builds a URI that loads an external JavaScript file. The external JavaScript file runs and loads an <iframe> into a <div> of my component. This external JS contains document.getElementById to load the <iframe> into the specified <div>.
I have searched and haven't found a way to force the <div> element to be exposed/placed in the shady DOM. I have read that if I design the component without a shadow DOM nothing will be displayed.
Is there anyway I can update this to web components v1/Polymer 2 with the external script (third party) still using document.getElementbyId to modify a <div> inside the web component?
UPDATE
I have found that I can force webcomponents to use the shadow dom using <script>window.ShadyDOM = { force: true };</script> or <script src="/bower_components/webcomponentsjs/webcomponents-lite.js" shadydom></script> however I still cannot access the element by ID and I do not want to force all other webcomponents to use the shady DOM. Still looking for possibilities.

What I had to do was put a <slot></slot> inside my Web Components template. When I declare the custom element, I have to nest a <div> inside of it like so: <custom-element><div></div></custom-element> which I am doing using this.appendChild() where this is the custom element. The <div> inside my element can now be accessed by document.getElementById() once it is assigned an id attribute.

Related

Assert css of an element using Dusk

I need to assert the styles of an element directly from the Dusk tests. In my application, I changed some styles of elements based on a specific condition. e.g. For invalid users, I changed the background to red. Now, I need to assert the css styles from Dusk.
Note that I don't want to check the class attribute. I want to check the styles that the class added to the element.
It has been solved. I used the web driver developed by Facebook. So, using it, I've selected the proper tag using xpath. Then, I get the stylesheet property of the selected tag using the web driver. Here is the source code. Note that adding the facebook web driver is required.
$the_tag = $browser->driver->findElements(WebDriverBy::xpath('//*[#class="user-item d-flex justify-content-between align-items-center mb-3"]'))[0];
$this->assertEquals($the_tag->getCSSValue("background"),"red");

Ext Js - how to add html attribute to created iframe

How do I add an attribute to an iframe created in Ext Js 7.5.1? I have an iframe component and would like to add the attribute allow="geolocation *" to the iframe element.
Using the autoEl configuration mentioned here adds the attribute to the wrapping <div> not the <iframe> itself, which doesn't provide the desired behavior. Adding it after render also mentioned here does not appear to provide the desired behavior. I'm not exactly sure why, my guess is because it is added after the component is rendered, not "in" the component as it is being rendered, although I may be wrong on this.

AEM: Component Action Toolbar: Blank style list is visble

We have a component that has a child component, within that, there is another child (child-2) component added. When in author ui, child-2 component does have style icon (in component action toolbar); however clicking on that renders a blank list.
If that child-2 component is added as independent component style icon as well as list (when clicked on) is also visible (with all styles variation as defined in policy).
We tried various ways to debug it but can not. Can anyone please help us here
AEM style system works by defining the styles in the policies. These policies should use the exact path where the component can potentially be placed.
Example: If the component's path is
/apps/project/components/content/myheader then the policy will be defined at path similar to below
/conf/project/settings/wcm/policies/project/components/content/myheader/policy_xxx.
But this policy definition will be used in a path in a template where you would use your component. For example if your template name is templateA and the name of the responsivegrid where your component myheader will be placed is headerGrid then myheader's policy will be used here:
/conf/project/settings/wcm/templates/templateA/policies/jcr:content/headerGrid/project/components/content/myheader <cq:policy property>.
The styles defined in policy will then only be visible in the above responsive grid (parsys in old language). To allow this styles in any other path, in your temlate create the path as required and use the policy there.
Following the above example, if you want your stlyes to be available in a componentA in the TemplateA where componentA is placed in bodyGrid then use the policy here:
/conf/project/settings/wcm/templates/templateA/policies/jcr:content/bodyGrid/componentA/project/components/content/myheader <cq:policy property>.
This should resolve your problem as tested in my system. Unfortunately there is no sandbox public to show you an example.

Insert custom HTML in page DOM with Google Tag Manager

I've implemented GTM on my website. I'm wondering if is possible to add custom HTML/JS in a specific position of the DOM.
This is what I've inserted in my page:
<div class="myClass">
<p>foo</p>
<script>
dataLayer.push({'event':'myEvent'})
</script>
</div>
and on GTM I've set up a tag with this html:
<div class="test">this is a test</div>
<iframe src="www.foo.com" />
which is triggered on myEvent.
Unfortunatly this is not working correctly, my tag is inserted at the bottom of my web page and not inside the myClass div.
Am I doing something wrong or this is just not allowed by GTM?
Thanks.
"Not allowed" is perhaps a bit strong (as you can see it works to some extent), but tags that change visual aspects of the page are generally not recommended.
If you want to insert HTML at a specific location it would be better to create the element dynamically via javascript and append it to an existing element, so your HTML tag would look something like (untested):
<script>
var myDiv = document.createElement('div');
myDiv.setAttribute('class','test');
var container = document.querySelector('.myClass');
container.append(myDiv);
</script>
You would need to make sure that the element you append to is unique (if possible add an id rather than a class name). Tags are executed asynchronously, so it's a bit hard to say at which point in the loading process the HTML is appended (this will cause a reflow in the DOM which is an expensive operation for the client, so you do not want to do this too often).

Apply CSS dynamically in Angular app

In my angular application, i load URLs inside an iframe dynamically, i want to apply custom.css to the loaded url once the url is loaded inside an iframe.
I have tried it using ng-init with angular-css-injector function in iframe. It works, but the css is not applied. Probably it is getting called in the initial stage. Is there any angular feature to apply the function once the url is loaded in iframe?
Here is the code
HTML:
<iframe frameborder='0' ng-src="{{trustSrc(selected.imgurl)}}" ng-init="applyCSS()" frameborder="0" allowfullscreen>
</iframe>
App.js:
var routerApp =angular.module('DiginRt', ['ngMaterial','angular.css.injector'])
routerApp.controller('AppCtrl', ['$scope', '$mdSidenav','$sce', 'muppetService', '$timeout','$log', 'cssInjector',function($scope, $mdSidenav,$sce, muppetService, $timeout, $log,cssInjector) {
$scope.applyCSS = function() {
cssInjector.add("style.css");
console.log("loaded css dynamically");
}
Here is the plunker
The thing which you are trying is appending CSS to own page, and appending css do parent document would not be applied to the child document which is created by iframe (Iframe creates child document after src has been loaded into the DOM).
Simply you can not do this. You can dynamically add the style dynamically inside iFrame unless the domain of both be same.(Refer this SO Answers for add url for same domain)
By looking at your code it don't looks like your are trying to load different domain inside iframe on your domain.
Possible work around would be, you could pass one more query parameter inside url & maintain css code on the site which you want to load it inside your iframe on basis of query parameter.(use yepnope.js to load js conditionally)

Resources