Feb 08

JSONJSON, or JavaScript Object Notation, is fairly popular.
This is just my modest take on a ‘PHP Object Notation’ implementation.
Note that it is meant to follow how your mind works rather than being syntactically correct; therefore, associative arrays are used in a loose manner where you have to worry about associative syntax as little as possible.
Basically, type away until your object is fully described.

Here is a notation sample:

PHP
  1.         ‘root level’ => array(
  2.                 ’sublevel 1′ => array(
  3.                         ’sublevel 2′ => ’sublevel 3′,
  4.                 ),
  5.         )
  6. );

.
This syntax can then be used the same way JSON is used, using eval. Here is how and you will immediately notice how the eval() syntax has to differ from the JavaScript one:

PHP
  1. $remote_str = <<<EOB
  2.     array(
  3.         ‘root level’ => array(
  4.                 ’sublevel 1′ => array(
  5.                         ’sublevel 2′ => ’sublevel 3′,
  6.                 ),
  7.         )
  8. );
  9. EOB;
  10. // …
  11. eval(‘$local_str=’.$remote_str.‘;’);

.
Feels a bit clumsy. Fortunately, starting with PHP4, if you are not too sad about introducing a statement in your remote string, you can rewrite it like this:

PHP
  1. $remote_str = <<<EOB
  2. return array(
  3.         ‘root level’ => array(
  4.                 ’sublevel 1′ => array(
  5.                         ’sublevel 2′ => ’sublevel 3′,
  6.                 ),
  7.         )
  8. );
  9. EOB;
  10. // …
  11. $local_str = eval($remote_str);

.
Better, isn’t it?

In this last listing, you will find the very simple code I wrote to traverse the object. Note that I invoke a callback for every element, otherwise this code would not be very helpful.

Note that this is just a concept for something I needed to throw together quickly therefore there are some limitations; for instance, you cannot have numeric keys since in this context their “keyness” is ignored and even feared.

PHP
  1. <?php
  2. function traverse_tree($callback, $curlevel, $curdepth, $uid)
  3. {
  4.         $depthstr = ‘——————————————————————————’;
  5.         $padding = substr($depthstr, 0, $curdepth);
  6.         if(!is_array($curlevel))
  7.         {
  8.                 $callback($curlevel, $padding, $uid);
  9.                 return;
  10.         }
  11.         foreach($curlevel as $level=>$children)
  12.         {
  13.                 if(!is_numeric($level))
  14.                 {
  15.                         $my_uid = $callback($level, $padding, $uid);
  16.                         traverse_tree($callback, $children, $curdepth + 2, $my_uid);
  17.                 }
  18.                 else
  19.                 {
  20.                         $callback($children, $padding, $uid);
  21.                 }
  22.         }
  23. }
  24.  
  25. function do_something($name, $padding, $uid)
  26. {
  27.         $iid = 0; // Bogus value
  28.         print $padding.$name." ($iid)\n";
  29.         return $iid;
  30. }
  31.  
  32. // ———————————————————–
  33. // Here we go
  34. // ———————————————————–
  35. if(count($argv) != 2)
  36.         die("\nSyntax: ".$PHP_SELF." ‘root_node_name’\n\n");
  37. $rootnodename = &$argv[1];
  38.  
  39. $INS = array(
  40.         $rootnodename => array(
  41.                 ‘Bikes’ => array(
  42.                         ‘Yamaha’ => ‘Fz’,
  43.                         ‘Honda’,
  44.                         ‘Norton’
  45.                         ),
  46.                 ‘Trikes’,
  47.                 ‘Cars’ => array(
  48.                         ‘Chevrolet’ => array(
  49.                                 ‘Corvette’ => array(‘Z06′, ‘Convertible’, ‘Coupe’),
  50.                                 ‘Camaro’,
  51.                                 ‘Jimmy’
  52.                                 ),
  53.                         ‘Ford’ => array(
  54.                                 ‘Mustang’ => array(‘GT’, ‘Premium’, ‘Shelby’, ‘Other’=>‘Roush’),
  55.                                 ‘Explorer’,
  56.                                 ‘Crown Victoria’
  57.                                 ),
  58.                         ‘Chrysler’ => array(
  59.                                 ‘Dodge’ => ‘Charger’,
  60.                                 ‘300X’,
  61.                                 ‘Le Baron’
  62.                                 ),
  63.                         )
  64.         )
  65. );
  66.  
  67. traverse_tree(do_something, $INS, 0, 1);
  68.  
  69. print "DONE\n\n";
  70. ?>

.
Invoke with:

  1. php my_php_script.php "Vehicles"

.
“What is this $iid variable?” you may ask.
You will notice that this piece of code is particularly convenient if you want to add a whole tree structure to your database. Say the you are using MySQL and want to create categories and sub-categories, using the column ‘pid’ as a category’s parent id. You would rewrite do_something:

PHP
  1. function do_something($name, $padding, $uid)
  2. {
  3.         mysql_query("INSERT INTO my_cat_table(pid, title) VALUES({$uid}, ‘{$name}’)");
  4.         $iid = mysql_insert_id();
  5.         print $padding.$name." ($iid)\n";
  6.         return $iid;
  7. }

Voila!

Sphere: Related Content

Feb 04

FlickosoftHere it is in all its glory. From Microsoft’s Press Page.
If you do a search for “microsoft yahoo” on Flickr, you will find a lot of interesting images; no idea whether this represents the opinion of only a few vocal people or if indeed Flickr users are, as a group, quite nonplussed.
A suggestion: if people are this much peeved, why not organize a massive exodus from Flickr, reducing its nominal value to zero? Now that would be grassroots…

Board of Directors
Yahoo! Inc.
701 First Avenue
Sunnyvale, CA 94089
Attention: Roy Bostock, Chairman
Attention: Jerry Yang, Chief Executive Officer
Dear Members of the Board:
I am writing on behalf of the Board of Directors of Microsoft to make a proposal for a business combination of Microsoft and Yahoo!. Under our proposal, Microsoft would acquire all of the outstanding shares of Yahoo! common stock for per share consideration of $31 based on Microsoft’s closing share price on January 31, 2008, payable in the form of $31 in cash or 0.9509 of a share of Microsoft common stock. Microsoft would provide each Yahoo! shareholder with the ability to choose whether to receive the consideration in cash or Microsoft common stock, subject to pro-ration so that in the aggregate one-half of the Yahoo! common shares will be exchanged for shares of Microsoft common stock and one-half of the Yahoo! common shares will be converted into the right to receive cash. Our proposal is not subject to any financing condition.
Our proposal represents a 62% premium above the closing price of Yahoo! common stock of $19.18 on January 31, 2008. The implied premium for the operating assets of the company clearly is considerably greater when adjusted for the minority, non-controlled assets and cash. By whatever financial measure you use - EBITDA, free cash flow, operating cash flow, net income, or analyst target prices - this proposal represents a compelling value realization event for your shareholders.
We believe that Microsoft common stock represents a very attractive investment opportunity for Yahoo!’s shareholders. Microsoft has generated revenue growth of 15%, earnings growth of 26%, and a return on equity of 35% on average for the last three years. Microsoft’s share price has generated shareholder returns of 8% during the last one year period and 28% during the last three year period, significantly outperforming the S&P 500. It is our view that Microsoft has significant potential upside given the continued solid growth in our core businesses, the recent launch of Windows Vista, and other strategic initiatives.
Microsoft’s consistent belief has been that the combination of Microsoft and Yahoo! clearly represents the best way to deliver maximum value to our respective shareholders, as well as create a more efficient and competitive company that would provide greater value and service to our customers. In late 2006 and early 2007, we jointly explored a broad range of ways in which our two companies might work together. These discussions were based on a vision that the online businesses of Microsoft and Yahoo! should be aligned in some way to create a more effective competitor in the online marketplace. We discussed a number of alternatives ranging from commercial partnerships to a merger proposal, which you rejected. While a commercial partnership may have made sense at one time, Microsoft believes that the only alternative now is the combination of Microsoft and Yahoo! that we are proposing.
In February 2007, I received a letter from your Chairman indicating the view of the Yahoo! Board that “now is not the right time from the perspective of our shareholders to enter into discussions regarding an acquisition transaction.” According to that letter, the principal reason for this view was the Yahoo! Board’s confidence in the “potential upside” if management successfully executed on a reformulated strategy based on certain operational initiatives, such as Project Panama, and a significant organizational realignment. A year has gone by, and the competitive situation has not improved.
While online advertising growth continues, there are significant benefits of scale in advertising platform economics, in capital costs for search index build-out, and in research and development, making this a time of industry consolidation and convergence. Today, the market is increasingly dominated by one player who is consolidating its dominance through acquisition. Together, Microsoft and Yahoo! can offer a credible alternative for consumers, advertisers, and publishers. Synergies of this combination fall into four areas:
Scale economics: This combination enables synergies related to scale economics of the advertising platform where today there is only one competitor at scale. This includes synergies across both search and non-search related advertising that will strengthen the value proposition to both advertisers and publishers. Additionally, the combination allows us to consolidate capital spending.
Expanded R&D capacity: The combined talent of our engineering resources can be focused on R&D priorities such as a single search index and single advertising platform. Together we can unleash new levels of innovation, delivering enhanced user experiences, breakthroughs in search, and new advertising platform capabilities. Many of these breakthroughs are a function of an engineering scale that today neither of our companies has on its own.
Operational efficiencies: Eliminating redundant infrastructure and duplicative operating costs will improve the financial performance of the combined entity.
Emerging user experiences: Our combined ability to focus engineering resources that drive innovation in emerging scenarios such as video, mobile services, online commerce, social media, and social platforms is greatly enhanced.
We would value the opportunity to further discuss with you how to optimize the integration of our respective businesses to create a leading global technology company with exceptional display and search advertising capabilities. You should also be aware that we intend to offer significant retention packages to your engineers, key leaders and employees across all disciplines.
We have dedicated considerable time and resources to an analysis of a potential transaction and are confident that the combination will receive all necessary regulatory approvals. We look forward to discussing this with you, and both our internal legal team and outside counsel are available to meet with your counsel at their earliest convenience.
Our proposal is subject to the negotiation of a definitive merger agreement and our having the opportunity to conduct certain limited and confirmatory due diligence. In addition, because a portion of the aggregate merger consideration would consist of Microsoft common stock, we would provide Yahoo! the opportunity to conduct appropriate limited due diligence with respect to Microsoft. We are prepared to deliver a draft merger agreement to you and begin discussions immediately.
In light of the significance of this proposal to your shareholders and ours, as well as the potential for selective disclosures, our intention is to publicly release the text of this letter tomorrow morning.
Due to the importance of these discussions and the value represented by our proposal, we expect the Yahoo! Board to engage in a full review of our proposal. My leadership team and I would be happy to make ourselves available to meet with you and your Board at your earliest convenience. Depending on the nature of your response, Microsoft reserves the right to pursue all necessary steps to ensure that Yahoo!’s shareholders are provided with the opportunity to realize the value inherent in our proposal.
We believe this proposal represents a unique opportunity to create significant value for Yahoo!’s shareholders and employees, and the combined company will be better positioned to provide an enhanced value proposition to users and advertisers. We hope that you and your Board share our enthusiasm, and we look forward to a prompt and favorable reply.
Sincerely yours,
/s/ Steven A. Ballmer
Steven A. Ballmer
Chief Executive Officer
Microsoft Corporation

Sphere: Related Content

Feb 03

References…almost :)
Another update:
After reading some of the comments to this entry, I googled ‘pass-by-reference’ and discovered that the semantic aspect of what the phrase means has been the topic of many topics along time with funny titles such as “More on Java- pass by reference, but not really” or more seriously “Parameter passing in Java - by reference or by value?” or what I consider the clearest, best articulated article on the topic: Java is Pass-By-Value, Dammit!
(end of update)

Next day update:
OK, thanks go to the first 3 commenters: when venturing into the semantic field, this entry is inaccurate. I should have used this title actually: Java Does Pass-A-Reference because it actually passes the reference’s value.
What does this mean? Well, Java passes a reference to the original object; however it passes a copy of its original reference.
After making this clear, you can keep reading because the point I am making - which is that the language’s behaviour, similar to C’s behaviour, should not come as a surprise - still stands and I am glad to be prompted to clarify it since it makes easier for the reader to grasp why modifying the argument does not change the reference :)
(end of update)

It is simple: either a function/method argument is an object, in which case a reference is passed, or it is not and the argument’s value is passed.
I just read this blog entry that somehow made it to DZone’s home page: Java Does Not Pass-By-Reference.
Well, it is unfortunate. The author makes the case that Java does not pass a reference to an object in a way that would allow him to manipulate said reference.
Of course, this is correct but I find the examples provided somewhat misguided since references themselves are not here to be manipulated but to let you manipulate the object (or, since he mentions C, the memory space) they reference.

Of course, to stay in tune with his C analogy, I should mention that you can modify the reference’s value itself if you use a pointer to a pointer in your function/method signature. For instance, in C, to modify a char* reference, this would look like this:

void myfunction(char **my_double_dereference)
{
    (*mydoublereference) = (char*)malloc(sizeof(char*)*my_size);
}

Now, our original memory space was not modified in the process. However, its reference was lost and replaced with a new reference to a new memory allocation.

C was originally written to be a better macro-assembler. With each new language generation, we are getting further away from the original intent by abstracting the architecture of the machine your program is compiled for. Java is one of the “recent” (Ahem! It’s all relative) languages that tried to free developers from having to worry about pointers. Of course, it quickly became obvious that if, on the one hand, it was easy to write a new program in Java, memory management was not going away and it is very difficult to write clean code if you do not understand its principles. (Note to some commenters: I never wrote that Java does away with pointers)

Note that if you wish to modify references in Java, you can still do that, but you have to be a bit more creative and wrap your reference in another object: this is, for example, how weak references work as you are actually passing a reference to the weak reference’s constructor. Not the object referenced.

Using the same model, let’s rewrite Adam’s Figure 4:

public static void main(String[] args) {
    StringBuffer sb1 = new StringBuffer("Hello");
    StringBufferWrapper wrapper = new StringBufferWrapper(sb1);
    doSomething(wrapper);
    sb1 = wrapper.reference;   

    // what gets printed?
    if (sb1 == null) {
        System.out.println("sb1 is null");
    } else {
        System.out.println("sb1 is not null");
    }
}   

public void doSomething(StringBufferWrapper sb2) {
    sb2.reference = null;
}

I hope I didn’t introduce any mistake in my code, it’s a tad late but you get the idea.

As usual, let me know if this elicits any question on this topic or weak references or what not…
Cheers!

Sphere: Related Content

Jan 24

Well, this is exciting:

Paul Bakaus, lead jQuery UI developer, announced today that he was hired by Liferay, Inc., of L.A., to work full time on his baby.

As an early adopter, I am very happy to see the project evolve this way. In case you are not familiar with Liferay, they develop open-source products, so all is well :)

Sphere: Related Content

Jan 03

Great news: with Leopard, there is no need for iCalFix anymore!
Bad news: iCalFix is not compatible with the new version of iCal and the latter keeps complaining about the former.
A lot of people have asked the author -BTW: thanks again, Robert, for creating iCalFix when it was needed- how to remove iCalFix but never got a reply.

Here is a veeery simple fix:

Simply remove the input manager from /Library/InputManagers

Using the shell:
sudo rm -rf /Library/InputManagers/iCalFix

Sphere: Related Content

Dec 26

SQLEvery now and then, a developer makes a post on their blog that, to the unsuspecting novice, seems like common sense.
Beware, though. If the post is less than comprehensive or accurate, it better not be about security matters or that newly acquired peace of mince may be quickly shattered.

Exhibit A: This post on the topic of PHP and SQL injections. It’s not like there is a lack of information already freely available on the web.
The author even references this excellent material at the end of his post. It is too bad that his own article actually contains less relevant information than the original post.

For instance, he recommends the use of mysql_real_escape_string().

  • Observation #1: this implies that you are using mysql as your database of choice. Granted you may use this method before sending a SQL query to Postgresql, but then there is no guarantee that mysql functions were compiled in the current php library.
  • Observation #2: mysql_real_escape_string() does nothing more than escape quotes. From the original article: “Be aware that “sanitizing the input” doesn’t mean merely “remove the quotes”, because even “regular” characters can be troublesome.

He recommends validating for the proper input, which is good practice. So, brownie points for that. But it wouldn’t hurt to have, for instance, mentioned the use of intval() to enforce that integer values are nothing but that. Integer values. I would say that it’s advice just as important as escaping input strings.

Now, the part that I found horrifying, but it’s just me, I’m a stickler: the author encourages you to code your HTML forms so that they will not accept too many characters. I see here some confusion: this is good usability advice, granted, but as far as security it is misguided.

The golden rule is simple: Always perform input validation server-side, where the user cannot ‘fake’ the values they are sending to your application.
Never, ever accept data “as-is” if it came through a path that allowed it to be tampered with.

Two other equally important points I wish he had mentioned are:

  • Configure error reporting so that your server does not display these “helpful” error messages that he mentions and attackers are delighted to find
  • A good SQL query is one cautiously put together, but a great SQL query relies on prepared statements. There are cases when you are after raw speed and direct queries feel more ‘natural’ -I know, I use them a lot- but whenever possible, use prepared statements, since the user is then not given a chance to “write” your query string himself.
Sphere: Related Content

Dec 22

LawyersOh, great.
Merry X-Mas and all that. Unless you’re ThinkSecret. Or Fake Steve Jobs. See here.
And here.

Of course, there is still the possibility that it’s another hoax created by our favourite Steve Jobs.

Here are two groups of people who are not about to get any more of my money if this is all true:

Apple:
Sorry, guys, but coolness is part of your products’ appeal. If you behave like a-holes, I will simply dedicate more of my time writing drivers for Linux.
I know, this isn’t the first time Apple enters ************ mode. But, obviously, after their ThinkSecret victory, there is enough blood in the water to keep the frenzy alive for a while.

The EFF:
Oh, come on guys. Again, I have no idea whether FSJ’ posts are pure hoax or the real thing. But when in doubt, I always get on my soap box. So, here goes: It is not the first time that I see a report of the EFF getting a less-than-positive result. And claiming victory over a site’s shuttering, I’m sure that FSJ is devastated, now that you made clear to him that freedom of speech is your thing, but only on your terms.

Merry Christmas, Happy Hanukah and Kwanzaa, or whatever else helps you live with yourselves.
Chris out.

Sphere: Related Content

Dec 14

I try to make this blog mostly about open-source and management. And I do not necessarily mean “open-source and management” in the same breath.
These just happen to be two topics that I live and breathe daily and, as they say: “Write about what you know”.

Anyway, today, both worlds collided and you can see the result at http://blog.mootools.net/2007/12/13/an-open-apology-to-the-authors-of-jquery-prototype-and-others
I am not going to comment on the original issue, this isn’t my goal. I simply think that it’s very instructive to read all the comments to that post. They raise some very interesting questions about management.
Was the author’s reaction “leadership?” What constitutes leadership, then? Is it knowing when to apologize? Is it sticking by your own troops?

I leave it to you to form your own opinion.

Sphere: Related Content

Dec 04

KodachiKodachi v0.5.1 is out! It’s good news for developers who want to write plug-ins or if you wish to change the look and feel of the application:

  1. A demo plug-in is now included. All it does is add a new direct word to Kodachi’s vocabulary: ‘Demo‘. Type it, select some action, and it will display a Growl-like notification confirming your action. A very easy starting place for budding plug-in developers.
    -
  2. Kodachi’s user interface is now skinnable. Actually this goes a bit beyond a simple skin as you can change its behaviour alltogether. Note that when launching Kodachi, you will now see the new demo skin, called ‘Bezel‘, that I created. If you are familiar with QuickSilver, this is certainly an interface you are already used to. If you wish to work with the old interface, simply disable the ‘BezelInterface’ plug-in.
    -
  3. The installer now checks which version of .Net is installed on your PC, if any, and offers to install the correct version if necessary.

Download Kodachi 0.5.1

Sphere: Related Content

Dec 02

Air LogoEver used GenPass? SuperGenPass?
What do you mean, you do not know what I am talking about? Oh, you need to read on.
Of course, I am referring to SuperGenPass, developed by Chris Zarate. This wonderful bookmarklet automatically generates strong passwords for you, based on the url of the web sites you are visiting. You only need to memorize your master password and that is all.
This is a great tool on so many levels. It works for broken brains -like mine: you take all your passwords with you wherever you go since all you have to do is use the bookmarklet in any foreign browser. It is secure: no password is in fact stored anywhere.

What are the advantages of Air GenPass?

  • Well, first of all, it allows you to run the tool with web browsers that do not provide correct support for bookmarklets. Safari for Windows, I am looking at you.
  • If you are a tad paranoid, like me, but have to use browsers that are unable to store such a big bookmarklet, for instance Internet Explorer or Opera, you may not wish to use Chris Zarate’s server to run it every time you need to regenerate a password.
  • If you are at a friend’s house and they do not wish to let you install a bookmarklet in their browser, no problem: GenPass is portable and you can carry it around with you on a USB stick. Of course, one may argue that they still have to agree to install Air ;)

Explaining how this application works is a breeze, mostly because there isn’t much to explain. When you open it, you see three text fields. Enter your master password in the bottom one and click on the tiny icon to close it. The top text field will contain the password generated by the tool and you will be able to copy them to the clipboard using its own icon. The middle field is the one where you will enter or paste the link of the site you are currently visiting. Since Air is a desktop application, you can alternatively grab the link’s icon in your browser’s address bar and drop it on the application.

You can stop reading here and download the application directly if you are not interested in the technology behind this simple guy.

This is my first Air application. So, how hard was it?

I used the latest release of Aptana, which is very nice for creating Air applications. That is, as long as your Air applications do not rely on Flex.

application.xml contains all the information pertaining to your application. Note that this information is not used by the Air installer. It seems that the installer only looks at the certificate used to sign your application. Since the only certificates currently available can be bought from Thawte for several hundred dollars, I believe that the fact that the installer does not claim that “Chris was here!” is a reasonable trade-off.

You can edit this file manually to provide information such as application license and icons.

AIRAliases.js is the library that links the objects used by Air’s bridge.

If you are a total Air newbie, just like I was before I wrote this tiny application, you have no idea what is this bridge that I am talking about.

The first iterations of Air -formerly known as Apollo- did not come with a security model and it was potentially possible to do all sorts of nasty things with Javascript code that could simultaneously talk to the Internet and clobber your local filesystem if it felt like it.
Adobe quickly introduced their own security model, which happens to be kind of kludgey but certainly makes sure that any connection between the World and your local resources is voluntary.

unsafe.html is a html page that is included in a frame. This simple fact means that it has access to all your web browser resources and no access to your computer’s resources. This is the Web sandbox and is usually used as presentation layer.
In my case, of course, because I am a little piggy, al l the presentation is done in the top frame, which happens to have access to your computer resources but cannot run queries to the World or execute arbitrary code through the use of eval() or setTimeout()
Joking aside, it is perfectly legit to use the top frame as presentation layer; it just makes your life harder if you use some libraries that make extensive use of eval()

GenPass.html is our top frame, just described in the previous paragraph. It contains a lot of Javascript and the definition of the iframe
container that links to unsafe.html. I have no right to be proud of this Javascript because I did not write most of it. It’s actually Chris Zarate’s supergenpass bookmarklet code, only modified just to the point where it can be included in an Air application. The rest of the code is the UI, which relies on jQuery. Because, good news, jQuery works on Air!

<iframe id=”unsafe”
src=”unsafe.html”
sandboxRoot=”http://voilaweb.com/”
documentRoot=”app-resource:/”
width=”0%”
height=”0%”
style=”border: 0px; margin: 0px; padding: 0px; width: 0%; height: 0%; visibility:hidden;”>
</iframe>

What’s really important here -save for the fact that I am setting all sizes to ‘0′ because I do not want to display the frame- is the src attribute. The page that will run in the web sandbox is unsafe.html

function notworking()
{
$(’#working’).css(’visibility’, ‘hidden’);
}

// Bridge
var Exposed = {};
Exposed.notworking = notworking;

$(document).ready(function() {
document.getElementById(’unsafe’).contentWindow.parentSandboxBridge = Exposed;

Do not blink: this is where it’s happening!
If it were not for this bit of code, we would not need our iframe. But since we wish to be able to invoke notworking() using setTimeout(), now we have to jump through hoops. Fortunately, these are simple hoops once you understand them.
First, we create an object called Exposed. We store a reference to our callback method in this object.
Then, when the DOM is ready according to jQuery, we take advantage of the fact that top frames are allowed to access the content of iframes: we store a reference to Exposed in the child document (remember that when we created our iframe, we gave it an id of ‘unsafe’? This is how we are accessing it now).

When the user clicks on the ‘Copy to Clipboard’ icon, we display an animated gif: a couple spinning arrows. We wish to display these guys for a second, then get rid of them. Of course, that’s the rub: since we are in the local sandbox, we cannot invoke setTimeout(). No problem! Let’s ask our child document, who lives in the Web sandbox, to do this for us. We are keeping, in our top document, a reference to the only method contained in the child document: localpause(). It is now time to invoke it. Let’s have a look at its content:

function localpause()
{
setTimeout(’parentSandboxBridge.notworking()’, 1000);
}

It is pretty straightforward: after a second, it will invoke the parent’s notworking() method, which will hide the animated gif (see above).

And that’s all there is to it, really.

Feel free to leave a comment if you have more questions.

I want to download it!

Oh, yes. Sure. Clicky.

Sphere: Related Content