/*----------------------------------------------------------------------------
   Copyright (C) Microsoft Corporation
  
   Licensed under the Apache License, Version 2.0 ("The Licence"). You may not
   use this file except in compliance with the License. A copy of the License
   can be found in the file "license.txt" at the root of this distribution.
----------------------------------------------------------------------------*/

// Utility function to access the DOM inside a browser.
module dom

import types

// Execute an action that gains access to the global ":window" object. 
public function withWindowsys/dom/withWindow: forall<e> (action : (window) -> <dom|e> ()) -> <dom|e> ()( actionaction: (window) -> <dom|_e> (): (windowsys/dom/types/window: V) -> <domsys/dom/types/dom: E|ee: E> (std/core/(): V) ) : <domsys/dom/types/dom: E|ee: E> (std/core/(): V)
{
  successsuccess: bool = applyWindowsys/dom/applyWindow: forall<e> (action : (window) -> <dom|e> ()) -> <dom|e> bool(actionaction: (window) -> <dom|_e> ());
  if (!std/core/(!): (bool) -> boolsuccesssuccess: bool) errorstd/core/error: forall<a> (string) -> exn a("this application can only run inside a browser")std/core/(): ()
}

external applyWindowsys/dom/applyWindow: forall<e> (action : (window) -> <dom|e> ()) -> <dom|e> bool : forall<ee: E> ( action: (windowsys/dom/types/window: V) -> <domsys/dom/types/dom: E|ee: E> (std/core/(): V) ) -> <domsys/dom/types/dom: E|ee: E> boolstd/core/bool: V { 
  js inline "(typeof window !== 'undefined' ? (function(){ (#1)(window); return true; })() : false)" 
}


// Execute an action after a specified time out.
public external timeoutsys/dom/timeout: forall<e> (msecs : int, action : () -> <dom|e> ()) -> <dom|e> () : forall<ee: E>( msecs: intstd/core/int: V, action: () -> <domsys/dom/types/dom: E|ee: E> (std/core/(): V) ) -> <domsys/dom/types/dom: E|ee: E> (std/core/(): V)
{ 
  js inline "window.setTimeout(#2,#1)" 
}

// Execute an action on a specified interval.
public external intervalsys/dom/interval: forall<e> (msecs : int, action : () -> <dom|e> ()) -> <dom|e> () : forall<ee: E>( msecs: intstd/core/int: V, action: () -> <domsys/dom/types/dom: E|ee: E> (std/core/(): V) ) -> <domsys/dom/types/dom: E|ee: E> (std/core/(): V)
{ 
  js inline "window.setInterval(#2,#1)" 
}