[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