User Control in Folder Home Page Doesn't Initialize - javascript

I am programming Outlook 2003 add-in using Visual Studio 2008.
Add-in uses embedded user control in folder's home page, like as it was
recommended. Here is HTML code for folder's home page:
<html><head><style type="text/css">body{overflow: hidden}</style></head>
<body rightmargin = '0' leftmargin ='0' topmargin ='0' bottommargin = '0' onload='OnBodyLoad()'>
<script>
function OnBodyLoad()
{
var outlook = window.external.OutlookApplication;
FolderView.Initialize(outlook);
}
</script>
<object classid='clsid:C718A848-6C31-4897-8DA8-0EDE3A4C6F14'
id='FolderView' VIEWASTEXT width='100%' height='100%' />
</body>
</html>
HTML code is inserted in HTMLDocument property of the active explorer during
FolderSwitch event.
In control's OnLoad event, a reference to application instance is used
(which was passed as a parameter to its Initialize method), but sometimes
control is not initialized before OnLoad event is fired. It is just created,
but Initialize method is never invoked.
Does somebody has similar experiences? Is this usual behavior?

I have no experience with Outlook 2003 or any other version of it, BUT I know about html and JavaScript, so I would recommend to not fire the method instantly cause in some "browsers/clients" the values used inside or the things need it to continue inside the method are not available yet. You better add a delay when calling the method and maybe that will fix your problem, cause that have solved many of my problems in the past.
Example:
document.addEventListener('onload', function (e) { yourFunction(params); }, false);
NOTE: it might be onload or onbodyload.

Related

Can't attach mousedown event to embed element

I seem to have hit a wall with this crap and can't make sense of it. I have a page with a relatively complex SVG (it has 6 other smalled SVGs embedded into it) in it embeded inside embed tag. When I try to attach a mousedown event to it, it simply doesn't work. Here is the markup:
<body>
<embed type="image/svg+xml" src="images/cog.svg" id="cog">
</embed>
</body>
then in javascript I do
$(function(){
var cog = document.getElementById("cog");
document.addEventListener('mousedown', function(e){
console.log(e);
});
});
It doesn't work. Moreover when i attach events to document, they do not fire when I click on that embed object either!
I searched this thing for 3 hours and everywhere I look it appears as if the embed should support mousedown even without any problem. What is the problem here?
Edit:
If it's any help here is how the full markup looks like (I use Foundation framework):
If CORS aren't an issue, you can try :
document.querySelector('embed').addEventListener('load', function(){
this.getSVGDocument().addEventListener('mousedown', function(){
alert('hello')});
});
According to the specs:
3 . If the previous step determined that the content's type is
image/svg+xml, then run the following substeps:
If the embed element is not associated with a nested browsing context, associate the element with a newly created nested browsing context,[...]
Navigate the nested browsing context to the fetched resource, with replacement enabled, and with the embed element's node document's
browsing context as the source browsing context. (The src attribute of
the embed element doesn't get updated if the browsing context gets
further navigated to other locations.)
The embed element now represents its associated nested browsing context.
But I can't find anything about actually how it should handle events.
Nevertheless, it appears that when its src is set and returns something, the events are captured by the new context (whether reached or created).
See #Marius comment for a demo when no src is set, it fires the event.
I think the embed tag is sandboxed and can't be accessed from external sources. Just use the img tag.
$('#logo').click(function() {
alert('410');
});
img{
width: 200px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<h3>Click the SVG</h3>
<img id='logo' src="http://dev.w3.org/SVG/tools/svgweb/samples/svg-files/410.svg">

Prevent copy on an empty iFrame (GWT RichTextArea)

I am required to prevent copy from a form. Using a oncopy handler works just fine on all <input/>-type fields.
Yet I fail to apply it to our "richtextarea", which is basically an empty iframe (src="about:blank" for what I have been able to gather; the page is GWT-generated, and the people before me developped quite an extensive framework around it).
I am able to get the iframe in the JavaScript, but I fail to have a correct handler (I tried adding one that logs, but it never does).
I have tried frame.oncopy, frame.contentWindow.oncopy, frame.contentWindow.document.oncopy, frame.contentDocument.oncopy. None of these does log to the console when I copy the iframe's content.
Does somebody have any lead for me? Any help appreciated (I've been stuck on this for some days now).
Having a cross-compatible solution would of course be ideal, but the main target is Firefox (the page is only open via a custom container based on Firefox 10).
Edit 2015-03-24
For those who want to try some debug script, the component I have trouble with is the one demonstrated here.
I have some native methods in the Java project to execute some custom JavaScript on it.
Below is some of the JavaScript I have unsuccessfully tried.
var frame = document.getElementsByTagName('iframe')[0];
function disallowCopy() {
alert('Gotcha!');
return false;
}
frame.oncopy = disallowCopy;
frame.contentWindow.oncopy = disallowCopy;
frame.contentWindow.document.oncopy = disallowCopy;
frame.contentWindow.document.body.oncopy = disallowCopy;
frame.contentDocument.oncopy = disallowCopy;
even though oncopy is a non standard event https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/oncopy and that there is no reliable way to prevent copying text,
you can check out the following bin
ensure the frame is loaded
use iframe.contentDocument.body to attch the event

How to execute code before window.load and after DOM has been loaded?

Here is the circumstance:
I have 2 pages:
1 x html page
1 x external Javascript
Now in the html page, there will be internal Javascript coding to allow the placement of the window.onload, and other page specific methods/functions.
But, in the external Javascript I want certain things to be done before the window.onload event is triggered. This is to allow customized components to be initialized first.
Is there a way to ensure initialization to occur in the external Javascript before the window.onload event is triggered?
The reason I have asked this, is to attempt to make reusable code (build once - use all over), to which the external script must check that it is in 'order/check' before the Javascript in the main html/jsp/asp/PHP page takes over. And also I am not looking for a solution in jQuery #_#
Here are some of the links on Stack Overflow I have browsed through for a solution:
Javascript - How to detect if document has loaded (IE 7/Firefox 3)
How to check if page has FULLY loaded(scripts and all)?
Execute Javascript When Page Has Fully Loaded
Can someone help or direct me to a solution, your help will be muchness of greatness appreciated.
[updated response - 19 November 2012]
Hi all, thanks for you advice and suggested solutions, they have all been useful in the search and testing for a viable solution.
Though I feel that I am not 100% satisfied with my own results, I know your advice and help has moved me closer to a solution, and may indeed aid others in a similar situation.
Here is what I have come up with:
test_page.html
<html>
<head>
<title></title>
<script type="text/javascript" src="loader.js"></script>
<script type="text/javascript" src="test_script_1.js"></script>
<script type="text/javascript" src="test_script_2.js"></script>
<script type="text/javascript">
window.onload = function() {
document.getElementById("div_1").innerHTML = "window.onload complete!";
}
</script>
<style type="text/css">
div {
border:thin solid #000000;
width:500px;
}
</head>
<body>
<div id="div_1"></div>
<br/><br/>
<div id="div_2"></div>
<br/><br/>
<div id="div_3"></div>
</body>
</html>
loader.js
var Loader = {
methods_arr : [],
init_Loader : new function() {
document.onreadystatechange = function(e) {
if (document.readyState == "complete") {
for (var i = 0; i < Loader.methods_arr.length; i++) {
Loader.method_arr[i]();
}
}
}
},
load : function(method) {
Loader.methods_arr.push(method);
}
}
test_script_1.js
Loader.load(function(){initTestScript1();});
function initTestScript1() {
document.getElementById("div_1").innerHTML = "Test Script 1 Initialized!";
}
test_script_2.js
Loader.load(function(){initTestScript2();});
function initTestScript2() {
document.getElementById("div_2").innerHTML = "Test Script 2 Initialized!";
}
This will ensure that scripts are invoked before invocation of the window.onload event handler, but also ensuring that the document is rendered first.
What do you think of this possible solution?
Thanking you all again for the aid and help :D
Basically, you're looking for this:
document.onreadystatechange = function(e)
{
if (document.readyState === 'complete')
{
//dom is ready, window.onload fires later
}
};
window.onload = function(e)
{
//document.readyState will be complete, it's one of the requirements for the window.onload event to be fired
//do stuff for when everything is loaded
};
see MDN for more details.
Do keep in mind that the DOM might be loaded here, but that doesn't mean that the external js file has been loaded, so you might not have access to all the functions/objects that are defined in that script. If you want to check for that, you'll have to use window.onload, to ensure that all external resources have been loaded, too.
So, basically, in your external script, you'll be needing 2 event handlers: one for the readystatechange, which does what you need to be done on DOMready, and a window.onload, which will, by definition, be fired after the document is ready. (this checks if the page is fully loaded).
Just so you know, in IE<9 window.onload causes a memory leak (because the DOM and the JScript engine are two separate entities, the window object never gets unloaded fully, and the listener isn't GC'ed). There is a way to fix this, which I've posted here, it's quite verbose, though, but just so you know...
If you want something to be done right away without waiting for any event then you can just do it in the JavaScript - you don't have to do anything for your code to run right away, just don't do anything that would make your code wait. So it's actually easier than waiting for events.
For example if you have this HTML:
<div id=one></div>
<script src="your-script.js"></script>
<div id=two></div>
then whatever code is in your-script.js will be run after the div with id=one but before the div with id=two is parsed. Just don't register event callbacks but do what you need right away in your JavaScript.
javascript runs from top to bottom. this means.. if you include your external javascript before your internal javascript it would simply run before the internal javascript runs.
It is also possible to use the DOMContentLoaded event of the Window interface.
addEventListener("DOMContentLoaded", function() {
// Your code goes here
});
The above code is actually adding the event listener to the window object, though it's not qualified as window.addEventListener because the window object is also the global scope of JavaScript code in webpages.
DOMContentLoaded happens before load, when images and other parts of the webpage aren't still fully loaded. However, all the elements added to the DOM within the initial call stack are guaranteed to be already added to their parents prior to this event.
You can find the official documentation here.

Access/Copy/Clone an Element’s Event Listeners (or Edit the lineNumber and sourceName)

Scenario
I’m writing a Chrome extension / userscript to add a little usability to a third-party site. The page that the extension is made for has a few elements that have `click` event listeners attached (per-element, no bubbling) via `addEventListener` (the `onclick` and other properties are empty). My extension clones (`cloneNode`) one of the elements and appends it to the list.
For example with this,
<div id="list">
<div id="d1">A</div>
<div id="d2">B</div>
<div id="d3">C</div>
</div>
my extension would add a D element.
Problem
Extending the list works fine, but when the original nodes are clicked, they perform the expected action, while clicking the new one does nothing.
Tests
Test 1
I examined the event listeners of the elements in Chrome’s Developer Tools and tried copying the anonymous function to my new elements with `addEventListener` (making sure to duplicate the parameters), but that did not work. It did perform some of the expected actions, but not all of them.
Test 2
I tried anfilat’s suggestion of using the trick from [this question][1]. I inserted a `script` block that then called `addEventHanlder` for the new node, and it did indeed have the new handler (with a `sourceName` referring to the site—the page, not the `.JS` file—instead of the extension), however it still threw a variable not found error.
Hypothesis
I suspect that it is a domain issue because the click-handler calls a function in an external `.JS` as referenced in the `sourceName` and `lineNumber` of the event listener as seen below. Note that the `listenerBody` is identical, but the sources differ.
Question
Is there a way to access, copy, or clone the handlers of an element and/or edit the `lineNumber` and `sourceName`?
Appendix A: Diagrams
Figure 1: Handlers of original elements referring to a .JS on the site (with slight filename edits):
Figure 2: Handlers of new elements referring to the extension:
I wrote the small working test.
Crome extension inject script:
var myScriptElement = document.createElement('script');
myScriptElement.innerHTML =
'b=document.getElementById("button");' +
'c=b.cloneNode(true);' +
'b.parentElement.appendChild(c);' +
'c.addEventListener("click", function(e){foo("from new button")}, false);';
document.querySelector('head').appendChild(myScriptElement);
test html:
<html>
<script type='text/javascript' src='test.js'></script>
<body>
<button id='button'>test</button>
<script>
document.getElementById('button').addEventListener('click', function (event) {
foo('from page');
}, false);
</script>
</body>
</html>
and test.js:
function foo(text) {
console.log(text);
};

Best way of unobtrusive onload in plain JavaScript

What is the best unobtrusive way of invoking something after the page is being loaded in plain JavaScript? Of course in jQuery I would use:
$(document).ready(function(){...});
but I am not sure about the most reliable approach in plain js.
Clearly
window.onload = ...
is not proper solution, because it would overwrite previous declaration.
What I am trying to do is to insert an iframe into a div after the page is loaded, but maybe there are actually better ways of doing it. My plan is to do something like:
window.onload = function(divId){
var div = document.getElementById(divId);
div.innerHTML = "<iframe src='someUrl' .. >";
}
EDIT:
Apologies for not including all necessary details.
The script is not for my website - the idea is to show a part of my site (a form) on external web sites. The priority is to minimize the effort someone has to put to use my code. That is why I would like to keep everything in js file and absolutely nothing in <script> - except of <script src="http://my.website/code.js" />. If I change URL of an iframe or I would like to add some features, I would like to update the code on all other web sites without asking them to make any changes.
My approach might be wrong - any suggestions are very welcome.
//For modern browsers:
document.addEventListener( "DOMContentLoaded", someFunction, false );
//For IE:
document.attachEvent( "onreadystatechange", someFunction);
`attachEvent` and `addEventListener` allow you to register more than one event listener for a particular target.
See:
https://developer.mozilla.org/en/DOM/element.addEventListener
Also definitly worth looking at how jQuery does it:
http://code.jquery.com/jquery-1.7.js Search for bindReady.
Use window.addEventListener and the events load or DOMContentLoaded:
window.addEventListener('DOMContentLoaded',function(){alert("first handler");});
window.addEventListener('DOMContentLoaded',function(){alert("second handler");});
object.addEventListener('event',callback) will insert an event listener into a queue for that specific object event. See https://developer.mozilla.org/en/DOM/element.addEventListener for further information.
For IE5-8 use window.attachEvent('event',callback), see http://msdn.microsoft.com/en-us/library/ms536343%28VS.85%29.aspx. You can build yourself a little helper function:
function addEventHandler(object,szEvent,cbCallback){
if(typeof(szEvent) !== 'string' || typeof(cbCallback) !== 'function')
return false;
if(!!object.addEventListener){ // for IE9+
return object.addEventListener(szEvent,cbCallback);
}
if(!!object.attachEvent){ // for IE <=8
return object.attachEvent(szEvent,cbCallback);
}
return false;
}
addEventHandler(window,'load',function(){alert("first handler");});
addEventHandler(window,'load',function(){alert("second handler");});
Note that DOMContentLoaded isn't defined in IE lesser 9. If you don't know your recipient's browser use the event load.
Just put your script include at the very end of the document, immediately before or after the ending </body> tag, e.g.:
(content)
(content)
<script src="http://my.website/code.js"></script>
</body>
</html>
All of the markup above the script will be accessible via the usual DOM methods (reference). Obviously, not all ancillary resources (images and such) will be fully loaded yet, but presumably that's why you want to avoid the window load event (it happens so late).
The only real purpose of ready-style events is if you don't control where the script gets included (e.g., libraries) or you need to have something execute prior to the page load and something else after the page load, and you want to avoid having two HTTP requests (e.g., for two different scripts, one before load and one after).

Categories