code:
google.load("earth", "1");
function gemap_init()
{
google.earth.createInstance('gemap', initCB, failureCB);
}
function initCB(instance)
{
try {
ge = instance;
ge.getWindow().setVisibility(true);
console.log(ge.getPluginVersion());
google.earth.fetchKml(ge,
'http://example.com.au/maps/example.kml',
function (kmlObject) {
if (kmlObject) {
ge.getFeatures().appendChild(kmlObject);
}
if (kmlObject.getAbstractView() !== null) {
ge.getView().setAbstractView(kmlObject.getAbstractView());
}
}
);
} catch (e) {
console.log(e);
}
}
function failureCB(errorCode)
{
alert(errorCode);
}
google.setOnLoadCallback(gemap_init);
for some reason this is working in every browser on my PC - but when I test on random computers and browsers around the office it is failing to display the markers or move the camera from the kml.
operating systems and browsers range from XP to Vista, and using FF, Chrome, IE7, IE8 - there is no pattern to the failure.
failing plugins are the same version as working plugins.
this is becoming a hair-pulling event for me as i just can't see where the fail is.
EDIT:
just to make clear - it is working in all those browsers and all those OSs - but not always, and not consistently...
there is no change in the javascript or kml between it working and not working.
the kml is a valid document
all browsers report that they are using the same plugin version
The comment from Fraser has reminded that this question was left open...
We have resolved the problem by appending a unique ID which is regenerated whenever the KML data on the server is updated.
This seems to bust the GE cache and we no longer have any problems with missing or out of date data being loaded in the plugin.
Related
I am trying to get the absolute device orientation across different mobile devices (android + IOs) and browsers
in a more or less reliable way. I would rather be able to understand if the orientation I am receiving is relative and not show the compass instead of showing wrong values.
I have been googling back and forth for days and I haven't found a definitive answer yet (I am
a javascript and web dev novice).
I see that the Full-Tilt library should be doing exactly
that but it has a non commercial license. I intend to use this result in a potentially commercial project, moreover, I would like to understand what's happening.
Nowadays most deviceorientation events are returning relative values.
deviceorientationabsolute is not supported by firefox and it's an experimental feature, I can fallback on it when other things fail but it cannot be the main solution.
So far I've got to this line of reasoning (pseudocode):
if(mobile)
if(webkitmobilecompassheading)
window.addEventListener("deviceorientation", handleOrientationWebkit, true);
else if(deviceorientationabsolute)
window.addEventListener("deviceorientation", handleOrientationAbsolute, true);
else
"bad luck"
I have no idea where to look to understand how many devices I would miss out on with the following reasoning, and if there is a better way.
For Android it works auto, for iOS it needs to be clicked to start it.
Here's a part of code you can use for that
startBtn.addEventListener("click", startCompass);
function startCompass() {
if (isIOS) {
DeviceOrientationEvent.requestPermission()
.then((response) => {
if (response === "granted") {
window.addEventListener("deviceorientation", handler, true);
} else {
alert("has to be allowed!");
}
})
.catch(() => alert("not supported"));
} else {
window.addEventListener("deviceorientationabsolute", handler, true);
}
}
function handler(e) {
const degree = e.webkitCompassHeading || Math.abs(e.alpha - 360);
}
Full tutorial is here, try demo also
https://dev.to/orkhanjafarovr/real-compass-on-mobile-browsers-with-javascript-3emi
We have run in to, what seems like, a bug in Office.js on Office for Mac.
If you attach an event handler to DocumentSelectionChanged event that calls Excel.run the standard Excel "undo" functionality gets disabled. And this remains disabled until the add-in is unloaded (i.e. the event handler is unhooked).
You can replicate this problem by (for example), taking the Excel-Add-in-JS-CollegeCreditsTracker sample app and inserting the following block of code in app.initialize method.
Office.context.document.addHandlerAsync(
Office.EventType.DocumentSelectionChanged,
function () {
Excel.run(function (ctx) {
var activeCell = ctx.workbook.getSelectedRange();
activeCell.load(["address", "worksheet", "rowIndex", "columnIndex", "values", "formulas"]);
return ctx.sync().then(function () {
app.showNotification(activeCell.address);
});
}).catch(function (err) {
console.log(err);
});
},
null,
function (asyncResult) {
console.log("Handler added: " + JSON.stringify(asyncResult));
}
);
Note that this works fine on Excel Desktop an Excel Online.
Is there a specific reason, such as API version supported on Office for Mac, that this would be failing?
This answer on an unrelated question suggests that there's an alternative way to handle selection change in newer API versions (although it doesn't say how). In which case, is that a possible workaround for this?
We cannot use BindingChanged events because we want to know when the user moves in and out of bindings, when user switches worksheets etc.
Just want to let everyone know that this issue has been resolved by the Office team.
I am starting to build a restartless Firefox add-on and I am having trouble setting up the bootstrap.js. Everyone seems to agree that the core of a bootstrap.js is pretty much boilerplate code, along these lines:
const Cc = Components.classes;
const Ci = Components.interfaces;
function startup() {
let wm = Cc["#mozilla.org/appshell/window-mediator;1"].getService(Ci.nsIWindowMediator);
let windows = wm.getEnumerator("navigator:browser");
while (windows.hasMoreElements()) {
let domWindow = windows.getNext().QueryInterface(Ci.nsIDOMWindow);
// then can control what happens with domWindow.document
}
}
function shutdown() {}
function install() {}
function uninstall() {}
This code works and I can control things in the existing windows. For example, domWindow.alert("text") successfully creates a standard alert saying "text" on every window that is currently open.
However, I can't find any code that will allow me to do things in new windows; i.e. those created after the script runs. What is the correct way to handle the creation of new windows and gain control over them, to the point where I could get another "text" alert from one when it is created?
Edit: Using the nsWindowMediator class and the code sample from MDN, I now have this:
var windowListener = {
onOpenWindow: function (aWindow) {
try {
let domWindow = aWindow.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowInternal || Ci.nsIDOMWindow);
domWindow.addEventListener("load", function () {
domWindow.removeEventListener("load", arguments.callee, false);
//window has now loaded now do stuff to it
domWindow.alert("text");
}, false);
} catch (err) {
Services.prompt.alert(null, "Error", err);
}
},
onCloseWindow: function (aWindow) {},
onWindowTitleChange: function (aWindow, aTitle) {}
};
function startup(aData, aReason) {
// Load into any existing windows
try {
let wm = Cc["#mozilla.org/appshell/window-mediator;1"].getService(Ci.nsIWindowMediator);
let windows = wm.getEnumerator("navigator:browser");
while (windows.hasMoreElements()) {
let domWindow = windows.getNext().QueryInterface(Ci.nsIDOMWindow);
loadIntoWindow(domWindow);
}
} catch (err) {
Services.prompt.alert(null, "Error", err);
}
Services.wm.addListener(windowListener);
}
However, there is still no output from the onOpenWindow call - the "text" alert does not appear, nor does the error alert in the catch block. I can confirm that onOpenWindow is actually being entered; if I put a Services.prompt.alert() at the beginning of onOpenWindow, I get the alert when I create a new window. Unfortunately, I get an infinite loop of alerts and I have no idea why.
However, I can't find any code that will allow me to do things in new windows; i.e. those created after the script runs. What is the correct way to handle the creation of new windows and gain control over them, to the point where I could get another "text" alert from one when it is created?
The correct way to act on each window when it opens is to use addListener() from nsIWindowMediator. The example code below does this. The nsIWindowMediator is included in Services.jsm and is accessed through Services.wm.addListener(WindowListener). In order to use a window listener, you have to pass it an nsIWindowMediatorListener (ref2) object. An nsIWindowMediatorListener contains three keys: onOpenWindow, onCloseWindow, and onWindowTitleChange. Each should be defined as a function which will be called when the appropriate event occurs.
The MDN document How to convert an overlay extension to restartless in "Step 9: bootstrap.js" contains an example of a basic bootstrap.js which will run the code in the function loadIntoWindow(window) for each currently open browser window and any browser window which opens in the future. I have used code modified from this in a couple of different add-ons. The example is substantially similar to the code you are already using. The example is (slightly modified):
const Ci = Components.interfaces;
Components.utils.import("resource://gre/modules/Services.jsm");
function startup(data,reason) {
// Load this add-ons module(s):
Components.utils.import("chrome://myAddon/content/myModule.jsm");
// Do whatever initial startup stuff is needed for this add-on.
// Code is in module just loaded.
myModule.startup();
// Make changes to the Firefox UI to hook in this add-on
forEachOpenWindow(loadIntoWindow);
// Listen for any windows that open in the future
Services.wm.addListener(WindowListener);
}
function shutdown(data,reason) {
if (reason == APP_SHUTDOWN)
return;
// Unload the UI from each window
forEachOpenWindow(unloadFromWindow);
// Stop listening for new windows to open.
Services.wm.removeListener(WindowListener);
// Do whatever shutdown stuff you need to do on add-on disable
myModule.shutdown();
// Unload the module(s) loaded specific to this extension.
// Use the same URL for your module(s) as when loaded:
Components.utils.unload("chrome://myAddon/content/myModule.jsm");
// HACK WARNING: The Addon Manager does not properly clear all add-on related caches
// on update. In order to fully update images and locales, their
// caches need clearing here.
Services.obs.notifyObservers(null, "chrome-flush-caches", null);
}
function install(data,reason) { }
function uninstall(data,reason) { }
function loadIntoWindow(window) {
/* call/move your UI construction function here */
}
function unloadFromWindow(window) {
/* call/move your UI tear down function here */
}
function forEachOpenWindow(todo) {
// Apply a function to all open browser windows
var windows = Services.wm.getEnumerator("navigator:browser");
while (windows.hasMoreElements())
todo(windows.getNext().QueryInterface(Ci.nsIDOMWindow));
}
var WindowListener = {
onOpenWindow: function(xulWindow) {
var window = xulWindow.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDOMWindow);
function onWindowLoad() {
window.removeEventListener("load",onWindowLoad);
// Only add UI changes if this is a browser window
if (window.document.documentElement.getAttribute("windowtype")
== "navigator:browser")
loadIntoWindow(window);
}
window.addEventListener("load",onWindowLoad);
},
onCloseWindow: function(xulWindow) { },
onWindowTitleChange: function(xulWindow, newTitle) { }
};
While there is quite a bit more that your might want to do in your bootstrap.js code, the above is organized reasonably well and keeps all of the code to load into the Firefox UI within loadIntoWindow(window) and unloading the UI within unloadFromWindow(window). However, it should be noted that some UI elements you should only be adding/removing once (e.g. australis widgets, like buttons) and other elements (e.g. direct changes to the Firefox DOM) have to be added once in each window.
Unfortunately, I get an infinite loop of alerts and I have no idea why.
One of the significant differences between this example and what you are currently using is the test for the type of window that has opened. This is done so that we are only acting on newly opened windows which are browser windows instead of all newly opened windows:
if (window.document.documentElement.getAttribute("windowtype") == "navigator:browser")
loadIntoWindow(window);
The problem you describe of getting an infinite loop of alert() popups is caused by not checking to make sure that you are only acting on browser windows. The alert() popup is a window. Thus, you are calling alert() for every alert() window you open which, of course, just opens another alert() window on which you call alert(). This is your infinite loop.
Additional references:
1. Working with windows in chrome code
However, I can't find any code that will allow me to do things in new windows
When working with XPCOM objects you generally want to study their interfaces, which are often found on MDN. In this case your starting point would be nsIWindowMediator, since that's the service you're using in line 5.
As you can see it has an addListener function, which takes a parameter implementing nsIWindowMediatorListener. There's a code-example right there on the page.
But let's assume for the moment there isn't a code example. You could search for the interface on MDN, but it isn't listed. The next step would be searching MXR for the .idl. idl = interface description language
Once you got the interface contract you can more or less just implement it in javascript, at least for listeners. Implementing your own xpcom services would be a little more complicated.
Searching the addon sdk can often provide some hints too. In this case they don't seem to be using .addListener, but the file hints at another interesting service, which in turn you can find on MDN: nsIWindowWatcher.
Basically, if you're writing restartless addons you're rummaging through the entrails of firefox and will have to do some detective work to find the exact components you need. If you want something more convenient I would recommend the addon sdk, which provides a more organized but also more restricted set of commonly used APIs
How to check if device is Windows Surface Tablet and browser is chrome or IE using Javascript.
i have tried following code
function is_touch_device()
{
try {
document.createEvent("TouchEvent");
return true;
} catch (e) {
return false;
}
}
if(is_touch_device() )
{
if(navigator.userAgent.toLowerCase().indexOf('chrome')>-1)
{
//some stuff
}
}
i have searched for useragent
but i an not getting exact for surface.
how to check if device is surface and browser is chrome or IE
Using the navigator object you can access these data fields
navigator.appName <- gets app name may be misleading so also get the appCodeName
navigator.appCodeName; <-- alternate name
navigator.platform; <-- platform the user is on
http://www.w3schools.com/js/js_window_navigator.asp
window.navigator.pointerEnabled
This method returned true Surface devices.....
Though you can use navigator object to serve your purpose, I would suggest you to use modernizer for the same.
I was trying to access swf from javascript, so this example in livedocs is what I'm trying to modify. http://livedocs.adobe.com/flash/9.0/ActionScriptLangRefV3/flash/external/ExternalInterface.html#includeExamplesSummary
However,it is not working correctly for some reason. The problem I'm encountering
is that it does not work in Safari and in Firefox, it only works if I put an alert
in the function before javascript pass the value to swf. (seems like it needs some time)
I also tried to set a timer in as3, but timer doesn't work, only alert in js helps.
All I wanted to do is use js to tell the swf file to play ep1.swf.
Here's my js code:
document.observe('dom:loaded', function() {
$('episode1').observe('click', function() {
var params = {wmode : "transparent", allowScriptAccess:"always", movie:"header"};
swfobject.embedSWF("swf/float.swf", "header", "100%", "100%", "9.0.0","expressInstall.swf", "", params, "");
sendToActionScript("ep1.swf");
});
})
function thisMovie(movieName) {
if (navigator.appName.indexOf("Microsoft") != -1) {
return window[movieName];
} else {
//alert("aaa")
return document[movieName];
}
}
function sendToActionScript(value) {
thisMovie('header').sendToActionScript(value);
}
Here's my as3 code:
private function receivedFromJavaScript(value:String):void {
loader.load(new URLRequest(value));
}
I've been trying for a really long time, does anyone know how to fix this? Thanks.
The problem is that the SWF file isn't fully loaded by the time you try to call it. The flash player is probably loaded but it takes a while to load and initialise the swf file.
What you need to do is make a call from the SWF file to a javascript function when it's loaded and put your javascript there rather than in the page loaded handler that you seem to be doing now. That way you know that your flash application is properly initialized by then. The ExternalInterface class you are using has methods to let you call back into the javascript.
Use this code to get swf Object.
I tested this code on:
IE 9,8,7
Firefox 6.0.1
Netscape Navigator 9.0.0.6
Opera 11.5
Google chrome 13.0.782.215
Safari 3.2 (All In Windows OS)
and it worked fine.
function GetSWF(strName) {
if (window.document[strName] != null) {
if (window.document[strName].length == null)
return window.document[strName];
else
return window.document[strName][1];
} else {
if (document[strName].length == null)
return document[strName];
else
return document[strName][1];
}
}
Summary of a success:
I am using AC_RunActiveContent.js, as set up by Flash when published.
My swf is called fvar_js, as seen below:
AC_FL_RunContent(
...
'src', 'fvar_js',
...
I STRESS this because I NEVER had to use a function like thisMovie
in the post above to point to the swf object. I was able to use
fvar_js straightaway (well, sort of, as you shall see).
In my as3 code I had the lines:
if (ExternalInterface.available) {
ExternalInterface.addCallback("js_to_as_f", js_from_as_f);
}
where js_from_as_f was a function that changed the text in a textfield.
In the HTML I set up the following:
var timeoutId;
var js_initiate_callback = function() {
// This is the swf object:
fvar_js.js_to_as_f();
clearTimeout ( timeoutId );
}
var reset_fvar_f = function(new_val) {
fvar_val = new_val;
}
//js_initiate_callback();
timeoutId = setTimeout(js_initiate_callback, 1000);
I tried 1ms and 100ms, but the results were spotty. With 1000ms
this worked in IE, FF and Safari on a PC. Have not checked on Mac OS X.
The key, evidently, is to allow all objects and all object connections
time to get set up. I have no idea what the minimum time is.