[Laszlo-dev] pre-RFC: target-specific code

Oliver Steele steele at laszlosystems.com
Tue Nov 29 11:43:31 PST 2005


Here's a sketch of a proposal for supporting target-specific code  
such as use of the Flash APIs.  The competing goals are to allow  
developers of applications that are targeted only at the Flash  
runtime to use Flash features and API calls, while protecting against  
the risk that libraries or applications will unintentionally become  
Flash-specific.  I want to kick it around here before finishing it  
and posting it as an RFC, party because I just don't have time to  
finish it now but we need to start planning some work based on the  
main body of the proposal.

Overview
The purpose of this proposal is to allow OpenLaszlo developers to  
access features that are present in only some deployment targets,  
without reducing the portability of OpenLaszlo programs across  
multiple targets.  The immediate goal is to allow the use of Flash- 
specific APIs.  A secondary goal is to set the stage for proposals  
that will allow the inclusion of swf files that contain script, and  
target-specific library files.  It is also expected that this  
proposal will be useful in the development of DHTML or other non- 
Flash implementations of the OpenLaszlo platform.

The proposal adds a new attribute, @target, to <canvas> and  
<library>.  It also uses this attribute to mark target-specific  
code.  Target-specific code may only be contained within an  
application or library that declares the @target attribute; this  
prevents its accidental contamination into an application or library  
that is intended to support multiple targets (Flash and DHTML), while  
making it possible to use target-specific code within an application  
that is written for only one target.

Use case templates
[These are just templates, not actual use cases.]
- An application or library is intended to be portable across  
targets.  This proposal is intended to reduce the chance that the  
artifact makes unintentional use of target-specific features or APIs.
- An application or library requires features that are available in  
only some targets, and is not intended to support other targets.   
This proposal is intended to allow this, but to make obvious the  
failure mode where the application or library is compiled for a  
target that does not support these features.
- An application or library can make use of features that are only  
available in some targets, but has fallback behavior on other targets.

Base Proposal
1. Add a @target attribute to the <script> and <method> tags.  This  
has the effect of turning on support for special functions such as  
fscommand, that the Flash authoring tool compiles to bytecodes  
instead of function calls.  (It has the effect that #pragma  
'flashCompilerCompatability' does today, except that we should not  
define it in those terms, and under this proposal it would be a  
supported platform feature, which the #pragma is not.)

2. Add a @target attribute to <library> and <canvas>.  It is an error  
for an <canvas> or <library> element without a @target attribute to  
contain or include an element with a target.  It is an error for a  
<canvas> or <library> element with a @target attribute to contain or  
include an element with a differently-valued @target attribute.

These are valid when compiled for the swf target.
   <canvas target="swf">
     <script target="swf">
       fscommand("showmenu", false);
     </script>
   </canvas>

   <canvas target="swf">
     <method name="hidemenu" target="swf">
       fscommand("showmenu", false);
     </method>
   </canvas>

   <canvas target="swf">
     <view>
       <method name="hidemenu" target="swf">
         fscommand("showmenu", false);
       </method>
     </view>
   </canvas>

   <library target="swf">
     <script target="swf">
       fscommand("showmenu", false);
     </script>
   </canvas>

   <canvas target="swf">
     <include href="swf-library.lzx"/>
   </canvas>

   <canvas target="swf">
     <import src="swf-library.lzx"/>
   </canvas>

where swf-library.lzx =
   <library target="swf">...</library>

This will not have the expected result.  fscommand is not a defined  
function.
   <canvas>
     <script>
       fscommand("showmenu", false);
     </script>
   </canvas>

These are invalid, and produce compiler warnings:
   <canvas>
     <script target="swf">
       fscommand("showmenu", false);
     </script>
   </canvas>

   <canvas>
     <method name="hidemenu" target="swf">
       fscommand("showmenu", false);
     </method>
   </canvas>

   <canvas>
     <view>
       <method name="hidemenu" target="swf">
         fscommand("showmenu", false);
       </method>
     </view>
   </canvas>

   <canvas target="dhtml">
     <script target="swf">
       fscommand("showmenu", false);
     </script>
   </canvas>

(And ditto for <library>.)

3. An application is compiled for a specific target.  The target of  
the current implementation of the OpenLaszlo compiler is always  
"swf".  It is an error to compile an application whose canvas  
contains a @target attribute, for a different target.  Of the two  
programs below, the first can be compiled for (any supported version  
of) the Flash player, and the second could be compiled for DHTML by  
an OpenLaszlo DHTML compiler.  However, it would be an error to  
compile the first program for DHTML or the second for Flash.

The third program can be compiled for either target.

   <canvas target="swf">
     <button>Hello</button>
   </canvas>

   <canvas target="dhtml">
     <button>Hello</button>
   </canvas>

   <canvas>
     <button>Hello</button>
   </canvas>

Extensions
There are several optional extensions that require the above proposal  
and can be built on top of this, although the proposal above can be  
completely implemented without them.

Extension A: target-specific directories
If an application contains an attribute <canvas target="{target}">,  
then $LPS_HOME/lps/components/{target} and its subdirectories are on  
the include path for that application.  For example, if the  
components directory layout includes:
- components
-- base
-- charts
-- ...
-- swf
--- file1.lzx
--- a-swf-component
--- supergrid
-- dhtml
--- file2.lxz
--- a-dhtml-component
--- supergrid

then the following lines are valid except where marked:
   <canvas target="swf">
     <include href="file1.lzx"/>
     <include href="file2.lzx"/> <!-- invalid -->
     <include href="a-swf-component"/>
     <include href="a-dhtml-component"/>  <!-- invalid -->
     <include href="supergrid"/>  <!-- valid; resolves to components/ 
swf/supergrid -->
   </canvas>

   <canvas target="dhtml">
     <include href="file1.lzx"/>  <!-- invalid -->
     <include href="file2.lzx"/>
     <include href="a-swf-component"/>  <!-- invalid -->
     <include href="a-dhtml-component"/>
     <include href="supergrid"/>  <!-- valid; resolves to components/ 
dhtml/supergrid -->
   </canvas>

Issue: There's really two different things going on: inclusion of  
components that are only available for one target, and selection of  
components that have separate implementations (presumably with the  
same API) on different platforms.  These should be specified  
separately if this extension is turned into its own proposal.  In the  
first case, the target-specific directories should only be added to  
the search path when the application includes @target, to make it  
harder to accidentally rely on a target-specific file.  In the second  
case, the compiler should add the target-specific directories based  
on its knowledge of the target even if this is implicit (the compiler  
only compiles for one target) or is specified outside the source  
text.  This is necessary to allow a target-independent program to use  
these files.

Extension B: Import swfs
1. Add a @include-script attribute to <resource>.  A statement of the  
form <resource src="movie.swf" include-script="true"> will import  
movie.swf with its embedded ActionScript blocks intact.  A statement  
of the form <resource src="movie.swf">, without an @include-script  
attribute, is not guaranteed to include any scripting beyond play and  
repeat.

2. It is an error for an <canvas> or <library> without a @target  
attribute to contain a <resource> element with @include-script=true.   
It is an error for a <canvas> or <library> element with a @target !=  
"swf" to contain a <resource> element with @include-script=true.

Note: I originally used @target=swf instead of @include-script=true.   
This made rule 2 here a special case of rule 2 in the main proposal.   
However, it was a confusing name.

Legal:
   <canvas>
     <resource src="movie.swf"/>
   </canvas>

   <canvas target="swf">
     <resource src="movie.swf" include-script="true"/>
   </canvas>

   <library target="swf">
     <resource src="movie.swf" include-script="true"/>
   </library>

Illegal:
   <canvas>
     <resource src="movie.swf" include-script="true"/>
   </canvas>

   <canvas target="dhtml">
     <resource src="movie.swf" include-script="true"/>
   </canvas>

   <library>
     <resource src="movie.swf" include-script="true"/>
   </library>

Extension C: version-specific code
Extend this mechanism to target specific versions of each target; for  
example, swf7, swf8, swf9, Mozilla 1.1.  The original (unpublished)  
proposal got bogged down in a naming scheme for vendor, architecture,  
major, minor, and subminor versions, so I backed off from that to  
just "swf" versus "dhtml".  I'd like to add back the complexity only  
on demand, once we have more specific use cases.  It may be possible  
to use the @features proposal instead.

A sketch:
   <canvas target="swf">
     <!-- cannot  include target="swf:8" or target="swf:9" -->
   <canvas target="swf:8">
     <!-- can include target="swf:8" or target="swf", but not  
target="dhtml" -->
   <canvas target="swf>8">
     <!-- can include target="swf:8" or target="swf:9", but not  
target="swf:7" -->
   <canvas target="dhtml:Mozilla>1.0|Safari>=1.2">

Extension D: Conditional compilation
Make it possible to write script and XML that is only compiled for  
specific targets.  This is simple to specify and implement but  
increases the developer knowledge burden; again, I'll leave this out  
as long as possible.

A sketch:
   <script>
     if (target.matches('swf')) ...

   <canvas>
     <switch>
       <text target="swf">I'm running in the Flash player.<view>
       <text target="dhtml">I'm running in DHTML.<view>
       <text>This is the fallback.  I haven't the foggiest what I'm  
running in.<view>
     </switch>
   </canvas>

Issue: The @target attribute conflicts with <method target> and (less  
seriously) <a target>.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://openlaszlo.org/pipermail/laszlo-dev/attachments/20051129/4c0ee870/attachment-0001.html


More information about the Laszlo-dev mailing list