Chrome Extension: Access to frame elements - dom

I am developing a chrome extension (content script) to access web page content. I use the DOM to access all elements in page.
My code does not work correctly when the web page contains "frameset". In this matter I can count the frame number but I can't access to the frame content.
I use this code to count frame objects available on current page :
for frameset :
parent.frames.length
and for iframe :
document.getElementsByTagName("iframe").length
but the following code does not work :
parent.frames[0]
and returns "undefined".
My question:
How can I access to frame set elements inside a chrome extension (for both iframe and frameset)?

Similar to how Jerinaw approached it, I did the following via jQuery:
// Find the frame
var frame = $(document).find("frame[name='nameOfFrame']")[0];
// Callback once frame's internals are loaded
$(frame).load(function() {
accessFrame();
});
function accessFrame() {
// The following line is really important to accessing the frame's content.
var frameContent = frame.contentDocument;
// Notice that $(".objectSelectorClass") won't discover the object you're hunting for. You have to find it within the frame's contentDocument.
var objectInFrame = $(frameContent).find(".objectSelectorClass");
var objectInFrame_AlternateSyntax = $(".objectSelectorClass", frameContent)
// do stuff to objectInFrame
}

I'm running into the same problem. The frames are not iframes and they are in a frameset. What I had to do was an onload (for some reason addEventListener isn't working) to the frame but through it's contentWindow
for example:
From the main document
document.querySelector('#SomeFrameSelector').contentWindow.document.body.onload
Accessing the frame this way got me to the frames document and allowed me to attach the onload. Once fired using the same selector I was able to modify the frames content.

Related

Changing DOM content of konva container causes crash?

I try to save the content of my last konva stage object in a Map in window object. My original aim is to minimize the loading time when I want to open the same page that has been drawn. Things are going well within my own frame. However, when I load my frame which has Konva content in another window (which becomes the parent of my Konva frame), the konva frame crashes and the console does not show any errors.
My code snipplet looks like this:
var xjGraph = cachedGraphObject; //Konva graph that already drawn, loaded from a js Map in parent window
var containerDOM = document.getElementById(oldId);
var konvaJsContent = xjGraph.getStage().content; //get the div of "konvajs-content" class
var oldChild = containerDOM.firstChild;
oldChild.remove();
containerDOM.appendChild(konvaJsContent); //remove the old div of "konvajs-content" and replace it with the one that I want to show; I could use replaceChild() here, but I get the same result
PS: If there is another way to save a stage in browser and load it when I need it for later use, please kindly help. Very much appreciated!

Leaflet VideoOverlay controls

In one of my projects, I have to integrate video on a leaflet Map. I didn't use the extend layer method because the video can have arbitrary dimension and should behave as other elements's map. I'm using a videoOverlay element to do so.
But now I have a problem, how to provide a proper way for the users to controls the video? I try to add the attribute controls inside the html video tag but the controls don't appears.
So I think that my only solution now is to make an external Leaflet controls right ?
Is it possible to have the controls on the video, as classical html video tag ?
First, the getElement() method of L.VideoOverlay to get the relevant instance of HTMLVideoElement.
Then, since HTMLVideoElement is a subclass of HTMLMediaElement, it has a controls property you can modify.
Put together it should look like:
var overlay = L.videoOverlay( /* stuff */ ).addTo(map);
var el = overlay.getElement();
el.controls = true;
or even:
var overlay = L.videoOverlay( /* stuff */ ).addTo(map);
overlay.getElement().controls = true;
Please note that the HTMLVideoElement instance only exists after the L.VideoOverlay has been added to a L.Map.

No setBounds function for Leaflet imageOverlay

I'm reading an imageOverlay URL from an ArcGIS webserver that uses the leaflet getBound() coordinates as part of the URL (we have large maps that are filtered for the current window 'extent'). Apologies for not including the actual path (I'm working with sensitive client data). Eg:
http://myarcgiswebserver.com/MapServer/export/dpi=96&format=png32&bbox=27.119750976562504%2C-31.194007509998823%2C32.39044189453126%2C-29.692824739380754&size=1719%2C434
[bbox] = current imageBounds
When dragging my map the imageOverlay url is updated correctly but my leaflet window is no longer aligned to the imageBound values that were set when first adding the imageOverlay which results in a skewed output (this is my assumption):
The only workaround is to remove the existing imageOverlay and add a new one (which ruins the user experience as the map disappears then reappears each time the window is dragged or zoomed).
Am i approaching this problem incorrectly or would the introduction of a function to update the current imageBounds resolve this? Perhaps not a new function but the expansion of setUrl with additional parameters...?
Many thanks for any feedback...
As #ghybs pointed out, your use case might be better served by using the WMS
interface of your ArcGIS server.
Anyway, you say
The only workaround is to remove the existing imageOverlay and add a new one (which ruins the user experience as the map disappears then reappears each time the window is dragged or zoomed).
Well, that glitch is due to you probably doing something like:
Remove old overlay
Add new overlay
Wait until the image is received from the network
Wait one frame so the new overlay is shown
and instead you should be doing something like:
Add new overlay
Wait until the image is received from the network
Remove old overlay
Wait one frame so the new overlay is shown
The problem is just the async wait and the possible race conditions there, but should be easy to hack together, e.g.:
var activeOverlay = null;
var overlayInRequest = null;
map.on('moveend zoomend', {
// If we are already requesting a new overlay, ignore it.
// This might need some additional debouncing logic to prevent
// lots of concurrent requests
if (overlayInRequest) {
overlayInRequest.off('load', showOverlay);
}
overlayInRequest = L.imageOverlay( computeUrl( map.getBounds() ), myOverlayOptions );
overlayInRequest.on('load', showOverlay);
});
function showOverlay(ev) {
activeOverlay.remove();
activeOverlay = overlayInRequest;
activeOverlay.addTo(map);
overlayInRequest = undefined;
}
If you use an ImageOverlay but change its url dynamically, with a new image that reflects a new bounding box, then indeed that is the reason for the behaviour you describe: you display an image that has been generated using a new bbox, but positioned in the initial bbox, since the image overlay remains at the same geographical position on the map.
Instead, it sounds to me that you should use a TileLayer.WMS.
It would automatically manage the bounding box update for you. You may need to find the correct options to fit your service provider required URL syntax, though.
Example: http://playground-leaflet.rhcloud.com/yel/1/edit?html,output

tinyMCE - I need to limit width/height of text entered

I have a tinyMCE textarea in which I want to limit how large, in pixels, whatever the user enters. Really, I do. I know this is not how most people use tinyMCE, but we are allowing clients to enter and format their own ad text for an ad that is a specific size (407px by 670px). So I want to limit what they can enter to that particular size. I can't limit the number of characters, because that would vary depending on font style/size. I actually want the input to fit within a particular sized box.
I have successfully sized the editor area and turned off the resizing of the editor and the scrollbars (in Firefox anyway), but it will still let the user continue typing past the edges of the box. Is there ANY way to prohibit this?
http://www.retailpromoinc.com/RestaurantAdvertising.php
Thank you for your consideration, I have been wrestling with this for HOURS!
Its a complicated one, as far as i know is there no feature from the TinyMCE Api to do so. What you could try to do is to configure the iFrame that is created by TineMCE.
By:
function iFrameConfig() {
var iFrame = document.getElementById('textareaid_ifr');
iFrame.setAttribute('scrolling', 'no');
iFrame.style.width = '300px';
iFrame.style.height = '600px';
}
Looks like you will have to write an own plugin for this. I will show you the steps necessary for this.
Here is a tutorial on howto write an own plugin, this is not difficult.
You will have to check for the editor content heigth for each of the users actions (keyup, paste, aso.). Use the predefined tinymce event handlers for this.
If the size of 670px is smaller than the real size you will have to undo the last user action automatically using the following line tinymce.get('my_editor_id').undoManager.undo();
I based my solution on Thariama's idea with undo (THX).
setup : function(ed) {
ed.wps = {}; // my namespace container
ed.wps.limitMceContent = function(ed) {
if ((ed.wps.$textcanvas.height() + ed.wps.textcanvasDummyHeight) > ed.wps.iframeHeight) {
ed.undoManager.undo();
}
};
ed.onKeyDown.add(ed.wps.limitMceContent);
ed.onChange.add(ed.wps.limitMceContent); // change is fired after paste too
ed.onInit.add(function(ed) {
// cache selectors and dimensions into namespace container
ed.wps.$iframe = $("textarea.tinymce").next().find("iframe");
ed.wps.iframeHeight = ed.wps.$iframe.height();
ed.wps.$textcanvas = $(ed.wps.$iframe[0].contentDocument.body);
ed.wps.textcanvasDummyHeight = parseInt(ed.wps.$textcanvas.css("marginTop"), 10) + parseInt(ed.wps.$textcanvas.css("marginBottom"), 10);
});
}
Working demo. Works on keyDown and paste. Tested only in FF 12 and Chrome.

Pdf generation for dynamic contents

i am generating pdf report in my app,When the page contents exceeds over one page how to populate the contents,actually in this situation i tried to create one more new page by giving CGContextBeginPage();
but it is showing error like
: CGContextEndPage: Don't nest calls to this function -- the results will not be what you expect.
**** : CGContextBeginPage: Don't nest calls to this function -- the results will not be what you expect.
Can somebody tell me how to create pdf during this kind of situation.
You should have a variable that stores your current Y position as you are laying out content, incrementing this value by the height of the content (and any padding).
Each time you want to render some text or image etc, check that you have enough space on the page before rendering and if not end the current page and begin a new one. Check the space by looking at the current Y position, adding the content height to it and comparing to your page rect.
The errors you are getting are due to you nesting PDF page calls, the OS expects the following approach...
CGContextBeginPage
... render content for page 1
CGContentEndPage
CGContextBeginPage
... render content page 2
CGContentEndPage
However your code is most likely nesting these as follows...
CGContextBeginPage
... render content for page 1
CGContextBeginPage
... render content for page 2
CGContextEndPage
CGContextEndPage