Dynamic DFP Javascript - javascript

I'm sure this has been asked and answered before but I haven't been able to track down an answer so I'm asking again.
I'm trying to implement Google DFP. I was able to dynamically create inline javascript that was serving ads, so I know the admin side should be configured correctly.
We don't have any inline JS in our application though, so I'm trying to build it out dynamically with JS and I haven't had much luck.
I've pasted my JS here. Worth noting is that the top part (prior to ///// !EVENTS) is loaded immediately, whereas the bottom part is loaded inside a $(document).ready() call in case that could be a culprit.
The idea with the code is that each advertisement div has data attributes with the url, size, and id of the advertisement. Using this I loop through each add, defining the slot, once all slots are defined, I display all slots, and once that happens, I call the remaining DFP functions. Sounds like it should work (to me anyway), but its not.
Each console.log() call is occurring as expected, and when I inspect the googletag object logged by that last call, the debug log contains entries like: "Created slot: /[userid]/[ad div id]","Google service JS loaded","Created service: publisher_ads", "Associated publisher_ads service with slot /[userid]/[ad unit id]"; for each record.
I'm not sure if perhaps the Google service JS or created service calls happening for each ad unit is causing problems or expected behaviours, but nothing is being logged to the console except what I've logged and there doesn't seem to be any indication that I've found that something has gone wrong, its just not serving ads.
In the documentation, and in the version of the implementation I had working, there were inline scripts that did the display calls. I'm not sure if perhaps this has to be handled inline and somehow displays the results in the parent of the script tag that called it or something, but even when I make the display calls inline it isn't working, with no more or less logging going on, which leads me to believe something isn't working correctly during the defineSlot() step, but like I mentioned the googletag object's debuglog does indicate the slot was defined.
In my network pane, it seems that there is two calls to Google at http://partner.googleadservices.com/gampad/google_ads_gpt.js and http://www.googletagservices.com/tag/js/gpt.js which returns the required Javascript, but those are the only calls to Google being made (relating to ads, there is other analytics calls) and there are 4 ads on this page that should be loading so I would expect there would be more calls if the ads were actually attempting to be served.
Needless to say I'm at a loss. I'm sure the answer is staring me in the face but I haven't worked much with DFP, or ads at all really, so I'm not sure where else to look to track this down.
Thanks in advance for any direction.

I've actually got a working script which I'm pretty sure does what you are after.
https://github.com/coop182/jquery.dfp.js
You should be able to get some pointers from my script but just from looking at your codepen, one issue which I have spotted is that you are not using the actual DOM id of the adunit div which DFP will need. Anywhere you are using:
$(that).attr('data-id');
should be:
$(that).attr('id');
The calls to googletag.display also need to come after
googletag.pubads().enableSingleRequest();
googletag.enableServices();

Related

How can I edit html inside an iframe using javascript

I am working on automating a process within my business, part of which is sending an email through SalesForce. We don't have access to the SF API and the email has to be sent through salesforce in order to keep the communication searchable for the coworkers.
I need to use a template which can be selected in SalesForce, however this function does not work in IE (which our RPA solution uses) so I need to build this email from scratch.
I see two options for this:
Use the HTML to recreate the format with the right variables. This entails inserting/injecting/manipulating HTML.
Copy the format into memory/the clipboard, edit it programatically and paste it into the SF interface
This question will be about option 1. I will post an additional question with regards to the second option separately and edit this question to include that link. EDIT: Here is the link to the other question!
Now on to the question:
We use the Blue Prism RPA software suite. It has a possibility to insert javascript fragments into a website and subsequently invoke them. I was hoping that I could create a javascript fragment that recreates the template, insert it and then invoke it. I have been working on this for the past week and have hardly gotten any further.
I now am able to add basic text into the required field, but have found that to be able to use the template structure I need to use a different, HTML based, field. This field I find lives inside an iframe.
I have had zero experience with javascript prior to this week (luckily it seems similar to c# in which I do have experience) and now this iframe has me stumped. Apparently when you use Selenium or similar you can switch the driver to the new iframe but I don't have that option, it needs to be done through surface automation. Within javascript as well as the console I can not get it to target the separate document within the iframe. Apparently the iframe contents are not incorporated in that way in the bigger webpage.
So my question is this: How can I "switch focus" to the iframe using javascript? How can I then edit the iframe contents through javascript? Any help, tips etc. would be highly appreciated!
If you go to developer tools in the browser (F12 or right-click inspect) you can use the inpsect tool to get the path you are looking for. an iframe is just another window inside the window and once you have the 'base path' you can then extend further into the window from the iframe base path.
You can access frames one of two ways I know of;
document.getElementById('the frame you are looking for goes here').contentWindow.targetFunction();
and/or
window.frames[0].otherfunctions
where 0 is the Nth order of frame on the window in case there are others.
once you find that path you can interact with sub-elements on that iframe by getting the path to it from within the iframe.
some things to watch out for. frames not loading yet so make sure the frame you want is loaded and no other frame is moving it around the screen at run time. Also make sure the child frame is in the same domain, I think calling javascript has issues when going cross-domain i.e. it doesn't work (stand to be corrected there though maybe it depends on group settings)
Supply some code or the layout of the page and could give you a code example but top of my head the format will look like this
var doc = window.frames[0]
var thing = getElementById(doc.getElementByPath('maybePath')
'perform some set operations like set innerhtml to thing you desire

Ionic 3 : How to preload tabs?

I'm in a particular case where I absolutely need to make sure that document.querySelectorAll('.scroll-content')[0], document.querySelectorAll('.scroll-content')[1], etc are defined before the user enters the app. In other words : I need to preload my tabs.
The current behavior of tabs :
doc...All('.scroll-content')[0] is defined.
doc...All('.scroll-content')[1] is undefined.
doc...All('.scroll-content')[2] is undefined.
doc...All('.scroll-content')[3] is undefined.
The reason for this "state" is that the content of the page of a tab is loaded only when it is visited.
The behavior I expect from the tabs
doc...All('.scroll-content')[0] is defined.
doc...All('.scroll-content')[1] is defined.
doc...All('.scroll-content')[2] is defined.
doc...All('.scroll-content')[3] is defined.
So I need to be able to load the tabs pages before the user is visiting them for the first time.
Sadly the ionic team did remove the preloading of tabs in beta 12 because supposedly the AOT compilation is fast enough for us "not to need" to preload tabs. 😤
I also tried to set my #IonicPages priority to high and specifying that I want to preload modules in app.module.ts.
No success.
Any idea ?
PS : Please, no ugly stuff like programmatically selecting each tab before showing content. 🤮
EDIT : I'm still looking for a clean workaround, but I also posted a feature request on github. Feel free to participate.
Note that I speak from my own experience.
Background:
I came across very similar approach where I render some content on the page with some external engine and need to make a reference to HTML generated by it within an Angular component. The problem is that putting the code in after view init lifecycle function wasn't enough.
Possible Solutions:
You could use setTimeout to wait for the HTML to be rendered
You can tap into ngDoCheck and check if the HTML has been rendered (if document.querySelector is truthy then you know you can move to your script).
Tapping to `ngDoCheck is expensive (after your initial load, your checks will still be fired). Hence it is better to use a combination of while loop and setTimeout. See pseudo-code below:
-
ngOnViewInit() {
let isReady = false;
do {
if (document.querySelectorAll('.scroll-content').length > 0) {
isReady = true;
}
while (!isReady);
this.runMyCodeThatNeedsThePagePreloaded();
}
If you are using AOT and the ionic team is right (it is fast enough), I could see no reason why you would want to preload your tabs. Except maybe because you want to fetch some data?
If loading data is the case, you could fetch the data in something a tabService which you could inject in each tab.

Element present in Chrome Dev Tools but NOT in View Source - how is this possible?

Trying to troubleshoot some design issues on a website (built with OpenCart), and ran into an issue I've never seen before: an element shows up in Dev Tools but DOESN'T show up in View Source.
How is this possible? And how can I find the actual element?
The situation is, I had to modify the original template (category.twig) to change the "Add To Cart" button to "View"... and it works in the default category view, but as soon as any of the filters are selected, this happens... it reverts to the original view.. but it's still the same file (I added the path into the code itself, just to make sure I'm indeed looking at the same file, you can see in in the Code View portion of the screenshot).
So yeah... trying to trace where this "Add To Cart" is coming from, and being mighty confused as so why it's NOT showing up in View Source. And no, there's no JavaScript targeting the "view_button" DIV and transforming it into "Add To Cart" - I made the "view_button" DIV, it's custom.
Any advice?
Javascript can (and often does) create new elements in the document, that won´t appear on code view becasuse it does not execute javascript. I would advice you to download the entire page and then search for button-cart-text in js files or the whole document.
The document's source does not define the element statically, but the JavaScript creates the element dynamically. This is very common. The dev. tools show you the document as it exists in memory (it's current state), which will include anything that the JS caused to happen, but view...source shows you the actual source code of the static file that was initially loaded.
Source code is what the programmer wrote. Or, in the case of "View Source" in a browser, it is at least what the server responded with, which may have been written by hand or may be generated using various forms of compilation or bundling. A common example here would be a page rendered from templates (e.g. using Handlebars).
Live code, or at least live markup, is what you are seeing in the Elements pane in the browser console. You are seeing the DOM rendered in realtime, right before your very eyes. You are watching the program (i.e. the page and its subresources) execute and take effect. It is mutating, most likely due to JavaScript.
For extremely simple pages like example.com, the difference between the source code and the live code may be imperceptible, because nothing is modified at runtime. However, for more complex, real-world websites, the DOM is often modified while you are browsing the page so that it can respond to your clicks, your typing, or anything else. These modifications are extremely powerful and useful. However, as you have discovered, they make the source code and the live code diverge. This makes a programmer's life more difficult, while making a user's life easier.

Serialization of the full page DOM. Can I get at the JS code that is loaded up, or must I AJAX it separately?

I have a bug I'm trying to track down, and it is very difficult to do so because of the complexity of the web app. There are many frames, and many instances of Javascript code that is embedded into the HTML in different ways.
The thing that needs to be fixed is a sub-page created with showModalDialog (so you already know it's going to be a disaster), and I am hoping that I can find a way to serialize as much of the DOM as possible within this dialog page context, so that I may open it to the same content both when the bug is present and when it is not, in hopes of detecting missing/extra/different Javascript, which would become apparent by pumping the result through a diff.
I tried jQuery(document).children().html(). This gets a little bit of the way there (it's able to serialize one of the outer <script> tags!) but does not include the contents of the iframe (most of the page content is about 3 iframe/frame levels deep).
I do have a custom script which I'm very glad I made, as it's able to walk down into the frame hierarchy recursively, so I imagine I can use .html() in conjunction with that to obtain my "serialization" which I can then do some manual checking to see if it matches up with what the web inspector tells me.
Perhaps there exists some flag I can give to html() to get it to recurse into the iframes/frames?
The real question, though, is about how to get a dump of all the JS code that is loaded in this particular page context. Because of the significant server-side component of this situation, javascript resources can be entirely dynamic and therefore should also be checked for differences. How would I go about (in JS on the client) extracting the raw contents of a <script src='path'> tag to place into the serialization? I can work around this by manually intercepting these resources but it would be nice if everything can go into one thing for use with the diff.
Is there no way to do this other than by separately re-requesting those JS resources (not from script tags) with ajax?

Recaptcha - Script tag injection failing sporadically

I have a form which uses reCAPTCHA. For some reason, when a user submits this form with an incorrect recapture value, when the page is re-rendered, the recapture fails to render.
What it looks like it happening is that recapture attempts to inject a "script" tag, and sporadically (and only in certain browsers, certain environments, and in certain scenarios), it is failing to add that "script" tag to the DOM.
It happens like this:
1) There is some inline javascript embedded in the form that looks like this:
https://www.google.com/recaptcha/api/challenge?k=<our public key>
2) That script executes correctly and returns the following:
var RecaptchaState = {
site : <some value>,
challenge : <challenge key>,
is_incorrect : false,
programming_error : '',
error_message : '',
server : 'https://www.google.com/recaptcha/api/',
timeout : 18000
};
document.write('<scr'+'ipt type="text/javascript" s'+'rc="' + RecaptchaState.server + 'js/recaptcha.js"></scr'+'ipt>');
3) What typically happens after that, is that the script tag is injected into the page, recaptcha.js is loaded, and it will read RecaptchaState to make a call out to recaptcha to get the image to render.
However, in certain cases, for some reason, the script tag that should be added in 2) never appears to be added to the DOM, so recaptcha.js is never loaded, so the recaptcha is never rendered! I can see in the console after the page is rendered that the "RecaptchaState" exists and has the correct value, just no script tag to go with it.
So that's what is happening and I am really stumped as to why. I am only able to reproduce this in Firefox, and oddly enough, it only happens under certain conditions. For instance, if I am routing requests through fiddler, it will work every time, never fails. If I clear my cache before I submit the request, it will work every time. Sometimes, when I'm expecting it to fail, it works, and vice versa. So it's very sporadic.
So my thought is that maybe it is has something to do with the timing of the js loading which is interfering with the "document.write" statement. Maybe some other javascript is interfering with it or something like that. Just looking for some general ideas as to how I might attempt to figure this out, tests I can run, things I can look for, or any ideas as all really.
Thanks in advance
Update
Still no luck figuring this out. One thought I had ... we see no error messages in the firebug console which would indicate that anything is going awry, although something obviously is. Are there any utilities we could use to get a closer look at exactly what is going on in Firefox? I'm thinking of something like "Speed-Tracer" for Chrome, which gives you a very detailed timeline of events. The only problem here is that we cannot reproduce
it in Chrome.
As it turns out, we are also including some scripts through a tag management service called Ensighten. One of those scripts was temporarily hi-jacking the "document.write" function and changing it to call another function. They were, however, setting a callback method after some other things happened which would reset the "document.write" function to its usual state.
However, if the timing of script evaluation happened just right so that our recaptcha javascript was evaluated while the document.write function was in its altered state ... it was failing to inject our subsequent recaptcha js to the page.
That being said, it seems like that could be considered intrusive of the ensighten code to modify documnet.write in such a way, especially for a third-party js file. So I've asked them if there is anyway they could avoid doing that in their code.

Categories

Resources