CassisProject


short URL: http://cassisjs.org

Introduction

Conceived in late 2008(1), the goal of the CASSIS Project is universal javascript (JS) that works on the client and the server for scalable application logic. The primary use-case is writing code to implement application logic that runs in browsers, especially dynamic interfaces that make use of XMLHTTPRequest (XHR/AJAX/AHAH), and also runs on web servers.

Until typical hosting companies support running JS on the server, CASSIS code must run in at least two programming language environments, JS on the client, and something that can be made to resemble JS on typical hosting company servers, which turns out to be PHP.

CASSIS stands for: client and server scripting implementation subset.

Summary

live code: https://tantek.com/cassis.js

source code repository: https://github.com/tantek/cassis

updates and news: @cassisjs

CASSIS v0.1 is currently good for: functional programming, math, datetime computations, string processing, parsing, form validation.

License

CassisProject source code (including all examples, fragments, and functions provided below) is licensed under a Creative Commons Attribution Share-Alike license (for now). Please attribute to "Tantek Çelik" and link attribution to https://tantek.com

Including CASSIS

Use the following code to include cassis.js:

Clientside in HTML:

<script type="text/javascript" src="cassis.js"></script>

Serverside in PHP:

ob_start(); // stops the few HTML comments in CASSIS from being outputted
include 'cassis.js';
ob_end_clean();

Implementations using Cassis

Writing in CASSIS

Coding standards for compatibly writing in CASSIS.

  1. variable names must start with $. (for PHP compatibility)
  2. string concatenation must use strcat() function. (not '+' or '.' native operators)
  3. code outside of the cassis.js library MUST NOT use the js() test function.
    1. anything that depends on JS or PHP should be abstracted and placed into cassis.js.
  4. ...

Projects to be written

Troubleshooting

count is not a function

Problem: you get an error message like (e.g. on Safari / Develop / Show Error Console)

 TypeError: Result of expression 'count' [1] is not a function.

Diagnosis: you're likely declaring a global variable in your code after you have script src="" included CASSIS, perhaps with a line like:

 var count = 0;

Solution: remove the line of code assigning to count, recode your code to not depend on a global variable, or rename the variable to a global name that is unique to your site / path / application to avoid colliding with globals in others scripting libraries.

Details

Some of the details of how CASSIS works.

Detection

Due to the need to abstract some number of language differences in syntax and built-in functionality, a foundational library must be developed that can detect which language it is running in, and execute language specific code accordingly so that CASSIS v0 code itself will not require anything language specific.

The key to the CASSIS v0 foundational library is the detection and switching of code dependent on which programming language environment is currently running.

The following code(2) switches between javascript, PHP, C/C++ and Ruby if need be:

if ("00"==false) {/*javascript*/} 
else if ("0"==false) {/*php*/} 
else if (0==false) {/*c*/} 
else {/*ruby*/}

For simplicity, it is sufficient to start with the ability to switch between javascript and one other language. From the possible candidates: PHP, Ruby, and C/C++, PHP is supported (nearly?) all web hosting environments and thus is the logical choice. We can simplify this test to check for JS or PHP environments as such:

function js() {
 return ("00"==false);
}

This function is called by any foundational library function that needs to execute different code for javascript vs. PHP as follows:

if (js()) {
 /* javascript */
}
else {
 /* PHP */
}

V0.1 code

The latest CASSIS v0.1 code is hosted live at:

https://tantek.com/cassis.js

Improvements in V0.1 over V0

V0 code

This section describes the initial functional version of CASSIS and is provided as historical documentation at this point (2010-031).

CASSIS v0 code is code that will run in PHP or javascript (and thus both on typical web servers, and typical web clients/browsers). Running CASSIS v0 code in javascript requires the use of an adapter library which re-implements some built-in PHP functions in javascript, documented in a latter section as cassisv0php.js.

CASSIS v0 code files must start with the following code sequence(3) to allow both PHP and javascript to execute properly:

<!-- <?php // -->

Similarly, CASSIS v0 code files must end with the following code sequence to properly balance and close out the PHP execution environment and the SGML/HTML comment opened at the start of the file in order to reduce/minimize any unintended effects of text outputted by PHP.

// ?> -->

common functions

One of best ways to avoid syntax differences between PHP and javascript is to use functions as much as possible. When PHP and javascript both have native (but differing in syntax) features for particular language functionality (e.g. string concatenation), the functionality must be abstracted in a common function.

The following block of CASSIS v0 code can be dropped into a CASSIS code file inline, or included as a separate cassis0.js file:

/* cassis0.js */
function js() {
 return ("00"==false);
}
function strcat($s1,$s2) {
 if (js()) { return $s1 + $s2; }
 else { return $s1 . $s2; }
}
/* end cassis0.js */

javascript only functions

When one language has a native feature that is implemented via a function (perhaps built-in) in the other language, it is better to use that function than the native feature, and then implement a compatibility function for the language with the native feature.

E.g. string length is implemented in javascript with the native "length" property, e.g. alert("foo".length) displays 3. In PHP string length is implemented as the strlen() function. Thus we re-implement strlen() as a function in javascript using its native "length" property.

The following block of javascript code can be dropped into a CASSIS code file inline, or included as a separate cassis0php.js file:

/* cassis0php.js - processed only by javascript */
// ?>
<!-- <?php $js=<<<EJS
/* --> /**/
function strlen(s) {
 return s.length;
} 
function ord(s) {
 return s.charCodeAt(0);
}
function substr(s,o,n) {
 var m = strlen(s);
 if (Math.abs(o)>=m) return false;
 if (o<0) o=m+o;
 if (n<0) n=m-o+n;
 return s.substring(o,o+n);
}
function explode(d,s,n) {
 return s.split(d,n);
}
function rawurlencode(s) {
 return encodeURIComponent(s);
}
function htmlspecialchars(s) {
 var c= [["&","&amp;"],["<","&lt;"],[">","&gt;"],["'","&#039;"],['"',"&quot;"]];
 for (i=0;i<c.length;i++) {
 s = s.replace(c[i][0],c[i][1]);
 }
 return s;
}
function str_ireplace(a,b,s) {
 return s.replace(new RegExp(a,"gi"),b);
}
/* more javascript-only functions here */
/*
EJS;
/**/
/* end cassis0php.js */

A precise sequence of common HTML/SGML comments <!-- -->, block comments /*...*/, one line comments //, PHP execution environment entering <?php and exiting ?>, and the PHP "heredoc" <<< block string format is used to declare a function in javascript which is seen only as a string value block of text by PHP. The concept of using overlapping multi-lingual comments to pass different content to different language interpreters was first proposed and demonstrated in Semantic Scripting (posted 2002年11月21日).

Using the above cassis0php.js code, CASSIS v0 code can call the "strlen" (to determine the length of a string) and "ord" functions, and such function calls will work in PHP or javascript.

PHP only functions

...to be written as needed.

History

Related Background

Some of the building block ideas / idea-fragments that inspired or were incorporated into CASSIS:

Reference

I have given the following talk on CASSIS and am available to give it at conferences, please contact me per CommunicationProtocols.

Title: CASSIS: Universal Client Server Javascript Now

Alternate Title: cassis.js: Code That Runs in both JS & PHP - Natively

Excerpt:

This talk is about how I use language hacks to run the same code natively on PHP and Javascript (JS), which I call CASSIS for Client And Server Scripting Implementation Subset.

I'll describe how I discovered CASSIS, how to use the open source library cassis.js to write middleware logic once for both client & server, and real-world use cases including where I've successfully deployed cassis.js for years (even as an essential part of my own site tantek.com).

Description:

This talk is about how I use language hacks* to run the same code natively on PHP and Javascript (JS), which I call CASSIS for Client And Server Scripting Implementation Subset.

Like any modern web developer, I want my site to work whether or not Javascript (JS) is supported, e.g. search engines which don’t execute it, on older browsers where users have disabled it, or perhaps most frequently, on mobile browsers with slow and unreliable network access that simply fails to load it. Tired of writing my code twice (once for JS, once for PHP), I started tinkering to see if there was a way to write code that would run in either simultaneously (without translation).

In this talk l’ll describe how I discovered CASSIS, how to use the open source library cassis.js to write middleware logic (math, datetime computations, string processing, parsing) once for both client & server, and real-world use cases including where I’ve successfully deployed cassis.js for years (even as an essential part of my own site tantek.com).

*You might be familiar with a previous language hack of mine: Box Model Hack.

Tags:

php, javascript, language, js, client, server


Return to MyNextStartup \ ProjectsList \ FrontPage.

AltStyle によって変換されたページ (->オリジナル) /