By following a few rules, you can create Desktop gadgets that work on multiple platforms.
Once you've written your gadget, you need to test it and specify the platforms that can execute the gadget.
The general rule is to follow the JavaScript conventions that are documented in David Flanagan's JavaScript, The Definitive Guide.
Although JScript is case insensitive, JavaScript is not. Take care to use the capitalization specified in the API reference documentation.
Example:
view.settimeout(update, 1000); view.SetTimeout(callback, 1000); view.setTimeOut(callback, 1000); view.SetTimeOut(callback, 1000);view.setTimeout(callback, 1000); //setTimeout is the proper capitalization.
Note: Google Gadgets for Mac checks for common capitalization mistakes and corrects them. However, it can't catch every mistake.
JScript features such as
collections
and (with one exception) ActiveXObject
work only on Windows.
You can find a partial list of JScript-only features by searching for
microsoft jscript "not compliant".
Example:
If you have code that uses collections syntax,
change it to use an accessor method such as putValue()
.
options("foo") = "bar";//Collections syntax is BAD. options.putValue("foo", "bar"); //GOOD!
Use the core JavaScript API,
the standard XMLHttpRequest class,
and the
W3C Level 1 DOM.
Avoid IE-specific DOM extensions,
just as if you were writing a multi-browser web application.
Also avoid non-standard properties such as parseError
.
Exceptions:
You can load images using
the responseStream
property of an
XMLHttpRequest
, as described
later.
You can also use the JScript Enumerator
object.
One common problem that causes gadgets to fail on the Mac is using
the text
property of Node
.
Instead, use a standard property such as
the XMLHttpRequest
properties
responseText
and responseXML
.
Example:
req = new XMLHttpRequest(); req.onreadystatechange = processXML; req.open("GET", url, true); req.send(); function processXML() { if (req.readyState == 4) { //request is finished if (req.status == 200) { //and successfulvar result = req.text;//text property is Windows only (BAD!) var result = req.responseText; //standard properties are GOOD } } }
The one exception to the rule of avoiding IE-specific DOM extensions
is that you can use a limited form of
the responseStream
property in an
XMLHttpRequest
.
Specifically, although you can't use any of
the Windows stream class methods,
you can use the responseStream
property
with framework.graphics.loadImage()
and img.src
.
Example:
//responseStream is OK only for getting image data. imageRequest = new XMLHttpRequest(); //... get the data and confirm it's good. Then: image.src = imageRequest.responseStream; //use image data
Finally, the isArray()
method is not standard JavaScript.
To detect whether an array contains any entries,
use standard JavaScript instead.
Example:
found = someString.match(expr);if (!isArray(found)) {//BAD: breaks on Mac if (found == null || !found.length) { //GOOD: cross-platform
If you must use Windows-specific APIs to write your gadget, go ahead. Just be sure to mark your gadget as Windows only, and please post to the developer group if a change to the Google Desktop APIs would allow your gadget to be cross-platform.
Desktop gadgets communicate with other gadget instances
using the googleTalk
object,
but Google Talk is supported only on Windows.
If your gadget absolutely needs Google Talk to work,
mark your gadget as Windows only.
If Google Talk isn't always essential for your gadget's operation,
then make sure your gadget behaves well
when Google Talk is unavailable.
The googleTalk
object
is present on Mac,
but it doesn't do anything.
Friends always appear to be offline,
and any data that's "sent" doesn't actually go anywhere.
Much of the information returned by the Windows-specific framework.system.perfmon
object is available through platform-independent API.
For example, to get information about system memory,
use the framework.system.memory
object instead of perfmon
.
Cross-platform gadgets cannot count on having access to any Google Desktop API that's marked as "Windows only" in the API reference documentation. Besides the Google Talk and perfmon interfaces, the major APIs that aren't supported for the Mac are the Query API and the Event API.
Note: For the first release of gadgets for the Mac, don't use any API introduced in Google Desktop for Windows 5.5. The 1.0 Mac gadgets API is equivalent to the Google Desktop for Windows 5.1 API, with no support for any API added in 5.5.
Gadgets that use native libraries such as DLLs are known as hybrid gadgets. A hybrid gadget can't be cross-platform.
With one exception, cross-platform gadgets
cannot use ActiveXObject
.
The exception is that
you can use the following code
to open a URL in an external web browser.
//The ONLY acceptable use of ActiveXObject in a cross-platform //gadget is opening a URL in a browser. var foo = new ActiveXObject('WScript.Shell'); foo.run(someURL);
Desktop gadgets run as widgets within the Dashboard application. This integration with Dashboard has two major consequences for Desktop gadgets:
For your gadget to not only run, but to be useful on the Mac, follow these guidelines.
Dashboard doesn't support drag or drop operations, so make sure your gadget has another way for the user to set its data.
For security reasons, Dashboard doesn't allow
Desktop gadgets to have read or write file system access.
The result is that function calls such as
gadget.storage.extract()
,
framework.system.getFileIcon()
,
framework.BrowseForFile()
, and
framework.BrowseForFiles()
don't work on the Mac.
If a gadget tries to browse the file system,
an error sheet shows up,
stating that file browsing isn't allowed.
Note:
Your gadget has access to all files inside its .gg
archive.
For security reasons, you can't invoke the
framework.system.network.wireless.connect()
and
framework.system.network.wireless.disconnect()
methods.
In Dashboard, a dragged gadget doesn't fire a mouse-down event until just before the mouse-up event. As a consequence, a gadget that performs animation on mouse-down on Windows might have no visible animation on the Mac.
Gadgets that rely on continual execution typically don't work well on the Mac. For example, a gadget that uses a continuously running timer, instead of the system clock, might have problems because the timer can't execute when Dashboard is hidden.
Gadgets that attempt to notify the user of events are also doomed to failure on the Mac, since a gadget can't make itself run or appear.
A gadget can have platform-specific code
if you isolate that code,
executing it only when the gadget is running on the relevant platform.
To detect the platform,
you can use the framework.system.machine.manufacturer
property,
which returns "Apple" if the gadget is running on a Mac.
Note:
For the first release of Google Gadgets for Mac,
don't use the framework.runtime.osName
property
or any other API introduced in Google Desktop for Windows 5.5.
The 1.0 Mac gadgets API
is equivalent to the Google Desktop for Windows 5.1 API,
with no support for any API added in 5.5.
Example:
function onMac() { return (framework.system.machine.manufacturer == "Apple"); } ... if (onMac()) { //mac code goes here } else { //win code goes here }
Even if your gadget breaks some cross-platform rules, it might still work everywhere, thanks to Google Gadgets for Mac's automatic correction of common problems. Testing your gadget is the only sure way to be sure that it works on both Windows and Mac. If you don't have access to a Mac, consider asking the developer group for testing help.
To run your gadget on the Mac,
just open the gadget's .gg
archive
by double-clicking or downloading it.
Google Gadgets for Mac automatically converts the gadget into a Dashboard widget,
adds it to Dashboard,
and shows Dashboard.
When you run your gadget,
you might discover some flaws
that you can fix by hand editing the gadget's files.
Here's how you can change your gadget and run the new version on the Mac
without rebuilding the gadget's .gg
file.
.gg
archive.
The gadget is converted to a widget and appears in Dashboard.
Press F12 or click the background to hide Dashboard.
Library/Widgets
folder.
Find the .wdgt
package
that corresponds to your gadget.
.wdgt
package
and choose Show Package Contents.
A Finder window appears that contains several files,
including an archive named gadget.gg
that contains
the Google Desktop files for your gadget.
gadget.gg
file and unzip it.
You can unzip it by renaming the copy to gadget.zip
and double-clicking it.
gadget.gg
file
by renaming it to gadget.gg.orig
..
gadget
)
to gadget.gg
.
gadget.gg
folder.
Although you can edit any of the files under this folder,
first go to the next step
to confirm that you can load a new copy of the existing gadget.
.js
or
.xml
files
under the gadget.gg
folder.
Repeat steps 8 through 10 as necessary.
Once you've finished making changes,
copy the changed files to
your gadget's project folder
and rebuild your gadget's .gg
file.
Be sure to test the new .gg
file
by opening it on both Windows and the Mac.
To specify the platforms your gadget works with,
use the <platform>
tag in the
gadget manifest file.
To allow pre-5.5 versions of Google Desktop for Windows
to read the version,
you also need to specify the
minimumGoogleDesktopVersion
attribute
of the gadget
tag.
If you know that your gadget works
on both Windows and Mac,
specify minimumGadgetHostVersion
attributes
for both the windows
and mac
tags.
<gadget minimumGoogleDesktopVersion="5.1.0.0"> <platform> <windows minimumGadgetHostVersion="5.1.0.0"/> <mac minimumGadgetHostVersion="1.0.0.0"/> </platform> ... </gadget>
If you're sure that your gadget doesn't work on Mac,
specify <mac supported="no"/>
.
<gadget minimumGoogleDesktopVersion="5.1.0.0"> <platform> <windows minimumGadgetHostVersion="5.1.0.0"/> <mac supported="no"/> </platform> ... </gadget>
If you're not sure whether your gadget works on Mac,
don't specify a <mac>
tag.
<gadget minimumGoogleDesktopVersion="5.1.0.0"> <platform> <windows minimumGadgetHostVersion="5.1.0.0"/> </platform> ... </gadget>