[Catalyst-commits] r7200 - in trunk/examples/RestYUI: db lib
lib/AdventREST/Controller root root/static root/user
jshirley at dev.catalyst.perl.org
jshirley at dev.catalyst.perl.org
Sun Dec 2 17:26:06 GMT 2007
Author: jshirley
Date: 2007-12-02 17:26:05 +0000 (Sun, 02 Dec 2007)
New Revision: 7200
Added:
trunk/examples/RestYUI/root/static/container.css
trunk/examples/RestYUI/root/static/datatable.css
trunk/examples/RestYUI/root/static/dt-arrow-dn.png
trunk/examples/RestYUI/root/static/dt-arrow-up.png
trunk/examples/RestYUI/root/static/json2.js
trunk/examples/RestYUI/root/static/sprite.png
trunk/examples/RestYUI/root/user/
trunk/examples/RestYUI/root/user/single_user.tt
Modified:
trunk/examples/RestYUI/db/adventrest.db
trunk/examples/RestYUI/lib/AdventREST.pm
trunk/examples/RestYUI/lib/AdventREST/Controller/User.pm
trunk/examples/RestYUI/root/index.tt
Log:
The rest of the RestYUI/AdventREST article
Modified: trunk/examples/RestYUI/db/adventrest.db
===================================================================
(Binary files differ)
Modified: trunk/examples/RestYUI/lib/AdventREST/Controller/User.pm
===================================================================
--- trunk/examples/RestYUI/lib/AdventREST/Controller/User.pm 2007-12-02 17:12:14 UTC (rev 7199)
+++ trunk/examples/RestYUI/lib/AdventREST/Controller/User.pm 2007-12-02 17:26:05 UTC (rev 7200)
@@ -4,6 +4,19 @@
use warnings;
use base 'Catalyst::Controller::REST';
+# If we have a form, return JSON data
+__PACKAGE__->config(
+ 'serialize' => {
+ 'default' => 'text/x-json',
+ 'map' => {
+ 'text/xml' => [ 'View', 'TT' ],
+ 'text/html' => [ 'View', 'TT' ],
+ # Remap x-www-form-urlencoded to use JSON for serialization
+ 'application/x-www-form-urlencoded' => 'JSON',
+ },
+ }
+);
+
=head1 NAME
AdventREST::Controller::User - Catalyst Advent Calendar REST Controller
@@ -39,7 +52,7 @@
my ( $self, $c ) = @_;
$c->log->debug( $c->req->content_type );
- $c->log->debug( $c->req->headers->as_string );
+ #$c->log->debug( $c->req->headers->as_string );
my %user_list;
my $user_rs = $c->model('DB::User')->search;
@@ -127,6 +140,7 @@
user_id => $user->user_id,
fullname => $user->fullname,
description => $user->description,
+ uri => $c->uri_for( $c->controller->action_for('single_user'), $user->user_id )->as_string
};
if ( $c->stash->{'user'} ) {
Modified: trunk/examples/RestYUI/lib/AdventREST.pm
===================================================================
--- trunk/examples/RestYUI/lib/AdventREST.pm 2007-12-02 17:12:14 UTC (rev 7199)
+++ trunk/examples/RestYUI/lib/AdventREST.pm 2007-12-02 17:26:05 UTC (rev 7200)
@@ -13,7 +13,7 @@
# Static::Simple: will serve static files from the application's root
# directory
-use Catalyst qw/-Debug ConfigLoader Static::Simple/;
+use Catalyst qw/ConfigLoader Static::Simple/;
our $VERSION = '0.01';
Modified: trunk/examples/RestYUI/root/index.tt
===================================================================
--- trunk/examples/RestYUI/root/index.tt 2007-12-02 17:12:14 UTC (rev 7199)
+++ trunk/examples/RestYUI/root/index.tt 2007-12-02 17:26:05 UTC (rev 7200)
@@ -2,34 +2,65 @@
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head>
<title>Advent! Now with more AJAX</title>
- <script type="text/javascript" src=""></script>
+ <link rel="stylesheet" href="/static/container.css" media="screen"/>
+ <link rel="stylesheet" href="/static/datatable.css" media="screen"/>
+ <script type="text/javascript" src="/static/yui/yahoo.js"></script>
+ <script type="text/javascript" src="/static/yui/event.js"></script>
+ <script type="text/javascript" src="/static/yui/utilities.js"></script>
+ <script type="text/javascript" src="/static/yui/connection.js"></script>
+ <script type="text/javascript" src="/static/yui/dom.js"></script>
+ <script type="text/javascript" src="/static/yui/element-beta.js"></script>
+ <script type="text/javascript" src="/static/yui/datasource-beta.js"></script>
+ <script type="text/javascript" src="/static/yui/datatable-beta.js"></script>
</head>
- <body>
+ <body class="yui-skin-sam">
<div id="user_list"></div>
<script type="text/javascript">
- /* Create the YAHOO.util.DataSource object, the parameter is the
- URI to your REST service
- */
- this.myDataSource = new YAHOO.util.DataSource("[%
- c.uri_for( c.controller('User').action_for('user_list') ) %]");
- this.myDataSource.responseType = YAHOO.util.DataSource.TYPE_JSON;
- this.myDataSource.connXhrMode = "queueRequests";
- this.myDataSource.responseSchema = {
- resultsList: "result_set.result",
- /* We have to define the fields for usage elsewhere */
- fields: [
- "pk1", "token", "default_lang", "languages",
- "url", "t_created", "t_updated", "actions"
- ]
- };
-
- myDataTable = new YAHOO.widget.DataTable(
- "user_list", myColumnDefs,
- this.myDataSource, {
- /* The initialRequest is appended to the URI to set params */
- initialRequest: "page=1&content-type=text/x-json"
+ var Catalyst = {};
+ YAHOO.util.Event.addListener(window, "load", function() {
+ Catalyst.Example = new function() {
+ /* Create a format function to make the name a link. */
+ this.formatName = function( cell, record, column, source_data ) {
+ cell.innerHTML = "<a href='" + record.getData("uri") +
+ ">" + source_data + "</a>";
}
- );
+
+ /* Create the YAHOO.util.DataSource object, the parameter is the
+ URI to your REST service
+ */
+ this.myDataSource = new YAHOO.util.DataSource("[%
+ c.uri_for( c.controller('User').action_for('user_list') ) %]?");
+ this.myDataSource.responseType = YAHOO.util.DataSource.TYPE_JSON;
+ this.myDataSource.connXhrMode = "queueRequests";
+ this.myDataSource.responseSchema = {
+ resultsList: "result_set.result",
+ /* We have to define the fields for usage elsewhere */
+ fields: [ "user_id", "fullname", "uri" ]
+ };
+
+ var myColumnDefs = [
+ /* Setup our column definitions, and make the entries link to
+ the detail record by using the formatName formatter */
+ { key: "user_id", label: "ID", sortable: true,
+ formatter: this.formatName },
+ { key: "fullname", label: "Full Name", sortable: true,
+ formatter: this.formatName},
+ /* We don't need to define all of the columns, and the
+ URI is only useful behind the scenes.
+ */
+ /*{ key: "uri", label: "Location", sortable: true },*/
+ ];
+
+ this.myDataTable = new YAHOO.widget.DataTable(
+ "user_list", myColumnDefs,
+ this.myDataSource, {
+ /* The initialRequest is appended to the URI to set params */
+ initialRequest: "page=1&content-type=text/x-json",
+ fields: [ "ID", "Full Name" ]
+ }
+ );
+ };
+ });
</script>
</body>
</html>
Added: trunk/examples/RestYUI/root/static/container.css
===================================================================
--- trunk/examples/RestYUI/root/static/container.css (rev 0)
+++ trunk/examples/RestYUI/root/static/container.css 2007-12-02 17:26:05 UTC (rev 7200)
@@ -0,0 +1,7 @@
+/*
+Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+Code licensed under the BSD License:
+http://developer.yahoo.net/yui/license.txt
+version: 2.3.1
+*/
+.yui-overlay,.yui-panel-container{visibility:hidden;position:absolute;z-index:2;}.yui-panel-container form{margin:0;}.mask{z-index:1;display:none;position:absolute;top:0;left:0;right:0;bottom:0;overflow:auto;}.yui-panel-container select{_visibility:inherit;}.masked select,.drag select,.hide-select select{_visibility:hidden;}.hide-scrollbars,.hide-scrollbars *{overflow:hidden;}.hide-scrollbars select{display:none;}.show-scrollbars{overflow:auto;}.yui-panel-container.show-scrollbars,.yui-tt.show-scrollbars{overflow:visible;}.yui-panel-container.show-scrollbars .underlay,.yui-tt.show-scrollbars .yui-tt-shadow{overflow:auto;}.yui-tt-shadow{position:absolute;}.yui-skin-sam .mask{background-color:#000;opacity:.25;*filter:alpha(opacity=25);}.yui-skin-sam .yui-panel-container{padding:0 1px;*padding:2px 3px;}.yui-skin-sam .yui-panel{position:relative;*zoom:1;left:0;top:0;border-style:solid;border-width:1px 0;border-color:#808080;z-index:1;}.yui-skin-sam .yui-panel .hd,.yui-skin-sam .yui-panel .bd,.yui-skin-sam .yui-panel .ft{*zoom:1;*position:relative;border-style:solid;border-width:0 1px;border-color:#808080;margin:0 -1px;}.yui-skin-sam .yui-panel .hd{border-bottom:solid 1px #ccc;}.yui-skin-sam .yui-panel .bd,.yui-skin-sam .yui-panel .ft{background-color:#F2F2F2;}.yui-skin-sam .yui-panel .hd{padding:0 10px;font-size:93%;line-height:2;*line-height:1.9;font-weight:bold;color:#000;background:url(sprite.png) repeat-x 0 -200px;}.yui-skin-sam .yui-panel .bd{padding:10px;}.yui-skin-sam .yui-panel .ft{border-top:solid 1px #808080;padding:5px 10px;font-size:77%;}.yui-skin-sam .yui-panel-container.focused .yui-panel .hd{}.yui-skin-sam .container-close{position:absolute;top:5px;right:6px;width:25px;height:15px;background:url(sprite.png) no-repeat 0 -300px;cursor:pointer;}.yui-skin-sam .yui-panel-container .underlay{right:-1px;left:-1px;}.yui-skin-sam .yui-panel-container.matte{padding:9px 10px;background-color:#fff;}.yui-skin-sam .yui-panel-container.shadow{_padding:2px 5px 0 3px;}.yui-skin-sam .yui-panel-container.shadow .underlay{position:absolute;top:2px;right:-3px;bottom:-3px;left:-3px;*top:3px;*left:-1px;*right:-1px;*bottom:-1px;_top:0;_right:0;_bottom:0;_left:0;_margin-top:3px;_margin-left:-1px;background-color:#000;opacity:.12;*filter:alpha(opacity=12);}.yui-skin-sam .yui-dialog .ft{border-top:none;padding:0 10px 10px 10px;font-size:100%;}.yui-skin-sam .yui-dialog .ft .button-group{display:block;text-align:right;}.yui-skin-sam .yui-dialog .ft .default{border-color:#304369;background-position:0 -1400px;}.yui-skin-sam .yui-dialog .ft .default .first-child{border-color:#304369;}.yui-skin-sam .yui-dialog .ft .default button{color:#fff;}.yui-skin-sam .yui-simple-dialog .bd .yui-icon{background:url(sprite.png) no-repeat 0 0;width:16px;height:16px;margin-right:10px;float:left;}.yui-skin-sam .yui-simple-dialog .bd span.blckicon{background-position:0 -1100px;}.yui-skin-sam .yui-simple-dialog .bd span.alrticon{background-position:0 -1050px;}.yui-skin-sam .yui-simple-dialog .bd span.hlpicon{background-position:0 -1150px;}.yui-skin-sam .yui-simple-dialog .bd span.infoicon{background-position:0 -1200px;}.yui-skin-sam .yui-simple-dialog .bd span.warnicon{background-position:0 -1900px;}.yui-skin-sam .yui-simple-dialog .bd span.tipicon{background-position:0 -1250px;}.yui-skin-sam .yui-tt .bd{position:relative;top:0;left:0;z-index:1;color:#000;padding:2px 5px;border-color:#D4C237 #A6982B #A6982B #A6982B;border-width:1px;border-style:solid;background-color:#FFEE69;}.yui-skin-sam .yui-tt.show-scrollbars .bd{overflow:auto;}.yui-skin-sam .yui-tt-shadow{top:2px;right:-3px;left:-3px;bottom:-3px;background-color:#000;}.yui-skin-sam .yui-tt-shadow-visible{opacity:.12;*filter:alpha(opacity=12);}
Added: trunk/examples/RestYUI/root/static/datatable.css
===================================================================
--- trunk/examples/RestYUI/root/static/datatable.css (rev 0)
+++ trunk/examples/RestYUI/root/static/datatable.css 2007-12-02 17:26:05 UTC (rev 7200)
@@ -0,0 +1,7 @@
+/*
+Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+Code licensed under the BSD License:
+http://developer.yahoo.net/yui/license.txt
+version: 2.3.1
+*/
+table.yui-dt-table{table-layout:fixed;}th .yui-dt-header{position:relative;}th .yui-dt-label{position:relative;}th .yui-dt-resizer{position:absolute;margin-right:-6px;right:0;bottom:0;width:6px;height:100%;cursor:w-resize;cursor:col-resize;}.yui-dt-scrollable{*overflow-y:auto;}.yui-dt-scrollable thead{display:block;}.yui-dt-scrollable thead tr{position:relative;}.yui-dt-scrollbody{display:block;overflow:auto;}.yui-dt-editor{position:absolute;z-index:9000;}.yui-skin-sam .yui-dt-table{margin:0;padding:0;font-family:arial;font-size:inherit;border-collapse:collapse;border:1px solid #7F7F7F;}.yui-skin-sam .yui-dt-table caption{padding-bottom:1em;text-align:left;}.yui-skin-sam .yui-dt-table th{background:url(sprite.png) repeat-x 0 0;}.yui-skin-sam .yui-dt-table th,.yui-skin-sam .yui-dt-table th a{font-weight:normal;text-decoration:none;color:#000;vertical-align:bottom;}.yui-skin-sam .yui-dt-table th,.yui-skin-sam .yui-dt-table td{padding:4px 10px 4px 10px;border-right:1px solid #CBCBCB;}.yui-skin-sam .yui-dt-table td{text-align:left;}.yui-skin-sam .yui-dt-table th.yui-dt-last,.yui-skin-sam .yui-dt-table td.yui-dt-last{border-right:1px solid #7F7F7F;}.yui-skin-sam .yui-dt-list td{border-right:none;}.yui-skin-sam .yui-dt-table thead{border:1px solid #989898;}.yui-skin-sam .yui-dt-table tbody{border-left:1px solid #7F7F7F;border-right:1px solid #7F7F7F;border-bottom:1px solid #7F7F7F;}.yui-skin-sam .yui-dt-loading{background-color:#FFF;}.yui-skin-sam .yui-dt-loading{background-color:#FFF;}.yui-skin-sam .yui-dt-sortable{cursor:pointer;}.yui-skin-sam th.yui-dt-sortable{padding-right:5px;}.yui-skin-sam th.yui-dt-sortable .yui-dt-label{margin-right:15px;}.yui-skin-sam th.yui-dt-asc,.yui-skin-sam th.yui-dt-desc{background:url(sprite.png) repeat-x 0 -100px;}.yui-skin-sam th.yui-dt-asc .yui-dt-header{background:url(dt-arrow-up.png) no-repeat right;}.yui-skin-sam th.yui-dt-desc .yui-dt-header{background:url(dt-arrow-dn.png) no-repeat right;}.yui-dt-editable{cursor:pointer;}.yui-dt-editor{text-align:left;background-color:#F2F2F2;border:1px solid #808080;padding:6px;}.yui-dt-editor label{padding-left:4px;padding-right:6px;}.yui-dt-editor .yui-dt-button{padding-top:6px;text-align:right;}.yui-dt-editor .yui-dt-button button{background:url(sprite.png) repeat-x 0 0;border:1px solid #999;width:4em;height:1.8em;margin-left:6px;}.yui-dt-editor .yui-dt-button button.yui-dt-default{background:url(sprite.png) repeat-x 0 -1400px;background-color:#5584E0;border:1px solid #304369;color:#FFF}.yui-dt-editor .yui-dt-button button:hover{background:url(sprite.png) repeat-x 0 -1300px;color:#000;}.yui-dt-editor .yui-dt-button button:active{background:url(sprite.png) repeat-x 0 -1700px;color:#000;}.yui-skin-sam tr.yui-dt-even{background-color:#FFF;}.yui-skin-sam tr.yui-dt-odd{background-color:#EDF5FF;}.yui-skin-sam tr.yui-dt-even td.yui-dt-asc,.yui-skin-sam tr.yui-dt-even td.yui-dt-desc{background-color:#EDF5FF;}.yui-skin-sam tr.yui-dt-odd td.yui-dt-asc,.yui-skin-sam tr.yui-dt-odd td.yui-dt-desc{background-color:#DBEAFF;}.yui-skin-sam .yui-dt-list tr.yui-dt-even{background-color:#FFF;}.yui-skin-sam .yui-dt-list tr.yui-dt-odd{background-color:#FFF;}.yui-skin-sam .yui-dt-list tr.yui-dt-even td.yui-dt-asc,.yui-skin-sam .yui-dt-list tr.yui-dt-even td.yui-dt-desc{background-color:#EDF5FF;}.yui-skin-sam .yui-dt-list tr.yui-dt-odd td.yui-dt-asc,.yui-skin-sam .yui-dt-list tr.yui-dt-odd td.yui-dt-desc{background-color:#EDF5FF;}.yui-skin-sam tr.yui-dt-highlighted,.yui-skin-sam tr.yui-dt-highlighted td.yui-dt-asc,.yui-skin-sam tr.yui-dt-highlighted td.yui-dt-desc,.yui-skin-sam tr.yui-dt-even td.yui-dt-highlighted,.yui-skin-sam tr.yui-dt-odd td.yui-dt-highlighted{cursor:pointer;background-color:#B2D2FF;}.yui-skin-sam .yui-dt-list tr.yui-dt-highlighted,.yui-skin-sam .yui-dt-list tr.yui-dt-highlighted td.yui-dt-asc,.yui-skin-sam .yui-dt-list tr.yui-dt-highlighted td.yui-dt-desc,.yui-skin-sam .yui-dt-list tr.yui-dt-even td.yui-dt-highlighted,.yui-skin-sam .yui-dt-list tr.yui-dt-odd td.yui-dt-highlighted{cursor:pointer;background-color:#B2D2FF;}.yui-skin-sam tr.yui-dt-selected td,.yui-skin-sam tr.yui-dt-selected td.yui-dt-asc,.yui-skin-sam tr.yui-dt-selected td.yui-dt-desc{background-color:#426FD9;color:#FFF;}.yui-skin-sam tr.yui-dt-even td.yui-dt-selected,.yui-skin-sam tr.yui-dt-odd td.yui-dt-selected{background-color:#446CD7;color:#FFF;}.yui-skin-sam .yui-dt-list tr.yui-dt-selected td,.yui-skin-sam .yui-dt-list tr.yui-dt-selected td.yui-dt-asc,.yui-skin-sam .yui-dt-list tr.yui-dt-selected td.yui-dt-desc{background-color:#426FD9;color:#FFF;}.yui-skin-sam .yui-dt-list tr.yui-dt-even td.yui-dt-selected,.yui-skin-sam .yui-dt-list tr.yui-dt-odd td.yui-dt-selected{background-color:#446CD7;color:#FFF;}.yui-skin-sam .yui-dt-paginator{display:block;margin:6px 0;white-space:nowrap;}.yui-skin-sam .yui-dt-paginator .yui-dt-first,.yui-skin-sam .yui-dt-paginator .yui-dt-last,.yui-skin-sam .yui-dt-paginator .yui-dt-selected{padding:2px 6px;}.yui-skin-sam .yui-dt-paginator a.yui-dt-first,.yui-skin-sam .yui-dt-paginator a.yui-dt-last{text-decoration:none;}.yui-skin-sam .yui-dt-paginator .yui-dt-previous,.yui-skin-sam .yui-dt-paginator .yui-dt-next{display:none;}.yui-skin-sam a.yui-dt-page{border:1px solid #CBCBCB;padding:2px 6px;text-decoration:none;}
Added: trunk/examples/RestYUI/root/static/dt-arrow-dn.png
===================================================================
(Binary files differ)
Property changes on: trunk/examples/RestYUI/root/static/dt-arrow-dn.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/examples/RestYUI/root/static/dt-arrow-up.png
===================================================================
(Binary files differ)
Property changes on: trunk/examples/RestYUI/root/static/dt-arrow-up.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/examples/RestYUI/root/static/json2.js
===================================================================
--- trunk/examples/RestYUI/root/static/json2.js (rev 0)
+++ trunk/examples/RestYUI/root/static/json2.js 2007-12-02 17:26:05 UTC (rev 7200)
@@ -0,0 +1,262 @@
+/*
+ json2.js
+ 2007-10-28
+
+ Public Domain
+
+ See http://www.JSON.org/js.html
+
+ This file creates a global JSON object containing two methods:
+
+ JSON.stringify(value, whitelist)
+ value any JavaScript value, usually an object or array.
+
+ whitelist an optional that determines how object values are
+ stringified.
+
+ This method produces a JSON text from a JavaScript value.
+ There are three possible ways to stringify an object, depending
+ on the optional whitelist parameter.
+
+ If an object has a toJSON method, then the toJSON() method will be
+ called. The value returned from the toJSON method will be
+ stringified.
+
+ Otherwise, if the optional whitelist parameter is an array, then
+ the elements of the array will be used to select members of the
+ object for stringification.
+
+ Otherwise, if there is no whitelist parameter, then all of the
+ members of the object will be stringified.
+
+ Values that do not have JSON representaions, such as undefined or
+ functions, will not be serialized. Such values in objects will be
+ dropped, in arrays will be replaced with null. JSON.stringify()
+ returns undefined. Dates will be stringified as quoted ISO dates.
+
+ Example:
+
+ var text = JSON.stringify(['e', {pluribus, 'unum'}]);
+ // text is '["e",{"pluribus":"unum"}]'
+
+ JSON.parse(text, filter)
+ This method parses a JSON text to produce an object or
+ array. It can throw a SyntaxError exception.
+
+ The optional filter parameter is a function that can filter and
+ transform the results. It receives each of the keys and values, and
+ its return value is used instead of the original value. If it
+ returns what it received, then structure is not modified. If it
+ returns undefined then the member is deleted.
+
+ Example:
+
+ // Parse the text. If a key contains the string 'date' then
+ // convert the value to a date.
+
+ myData = JON.parse(text, function (key, value) {
+ return key.indexOf('date') >= 0 ? new Date(value) : value;
+ });
+
+ This is a reference implementation. You are free to copy, modify, or
+ redistribute.
+
+ Use your own copy. It is extremely unwise to load third party
+ code into your pages.
+*/
+
+/*jslint evil: true */
+/*extern JSON */
+
+if (!this.JSON) {
+
+ JSON = function () {
+
+ function f(n) { // Format integers to have at least two digits.
+ return n < 10 ? '0' + n : n;
+ }
+
+ Date.prototype.toJSON = function () {
+
+// Eventually, this method will be based on the date.toISOString method.
+
+ return this.getUTCFullYear() + '-' +
+ f(this.getUTCMonth() + 1) + '-' +
+ f(this.getUTCDate()) + 'T' +
+ f(this.getUTCHours()) + ':' +
+ f(this.getUTCMinutes()) + ':' +
+ f(this.getUTCSeconds()) + 'Z';
+ };
+
+
+ var m = { // table of character substitutions
+ '\b': '\\b',
+ '\t': '\\t',
+ '\n': '\\n',
+ '\f': '\\f',
+ '\r': '\\r',
+ '"' : '\\"',
+ '\\': '\\\\'
+ };
+
+ function stringify(value, whitelist) {
+ var a, // The array holding the partial texts.
+ i, // The loop counter.
+ k, // The member key.
+ l, // Length.
+ v; // The member value.
+
+ switch (typeof value) {
+ case 'string':
+
+// If the string contains no control characters, no quote characters, and no
+// backslash characters, then we can safely slap some quotes around it.
+// Otherwise we must also replace the offending characters with safe sequences.
+
+ return /["\\\x00-\x1f]/.test(value) ?
+ '"' + value.replace(/[\x00-\x1f\\"]/g, function (a) {
+ var c = m[a];
+ if (c) {
+ return c;
+ }
+ c = a.charCodeAt();
+ return '\\u00' + Math.floor(c / 16).toString(16) +
+ (c % 16).toString(16);
+ }) + '"' :
+ '"' + value + '"';
+
+ case 'number':
+
+// JSON numbers must be finite. Encode non-finite numbers as null.
+
+ return isFinite(value) ? String(value) : 'null';
+
+ case 'boolean':
+ return String(value);
+
+ case 'null':
+ return 'null';
+
+ case 'object':
+
+// Due to a specification blunder in ECMAScript,
+// typeof null is 'object', so watch out for that case.
+
+ if (!value) {
+ return 'null';
+ }
+
+// If the object has a toJSON method, call it, and stringify the result.
+
+ if (typeof value.toJSON === 'function') {
+ return stringify(value.toJSON());
+ }
+ a = [];
+ if (value.constructor === Array) {
+
+// The object is an array. Stringify every element. Use null as a placeholder
+// for non-JSON values.
+
+ l = value.length;
+ for (i = 0; i < l; i += 1) {
+ a.push(stringify(value[i], whitelist) || 'null');
+ }
+
+// Join all of the elements together and wrap them in brackets.
+
+ return '[' + a.join(',') + ']';
+ }
+ if (whitelist) {
+
+// If a whitelist (array of keys) is provided, use it to select the components
+// of the object.
+
+ l = whitelist.length;
+ for (i = 0; i < l; i += 1) {
+ k = whitelist[i];
+ if (typeof k === 'string') {
+ v = stringify(value[k], whitelist);
+ if (v) {
+ a.push(stringify(k) + ':' + v);
+ }
+ }
+ }
+ } else {
+
+// Otherwise, iterate through all of the keys in the object.
+
+ for (k in value) {
+ if (typeof k === 'string') {
+ v = stringify(value[k], whitelist);
+ if (v) {
+ a.push(stringify(k) + ':' + v);
+ }
+ }
+ }
+ }
+
+// Join all of the member texts together and wrap them in braces.
+
+ return '{' + a.join(',') + '}';
+ }
+ }
+
+ return {
+ stringify: stringify,
+ parse: function (text, filter) {
+ var j;
+
+ function walk(k, v) {
+ var i, n;
+ if (v && typeof v === 'object') {
+ for (i in v) {
+ if (Object.prototype.hasOwnProperty.apply(v, [i])) {
+ n = walk(i, v[i]);
+ if (n !== undefined) {
+ v[i] = n;
+ }
+ }
+ }
+ }
+ return filter(k, v);
+ }
+
+
+// Parsing happens in three stages. In the first stage, we run the text against
+// regular expressions that look for non-JSON pattern. We are especially
+// concerned with '()' and 'new' because they can cause invocation, and '='
+// because it can cause mutation. But just to be safe, we want to reject all
+// unexpected forms.
+
+// We split the first stage into 4 regexp operations in order to work around
+// crippling inefficiencies in IE's and Safari's regexp engines. First we
+// replace all backslash pairs with '@' (a non-JSON character). Second, we
+// replace all simple value tokens with ']' characters. Third, we delete all
+// open brackets that follow a colon or comma or that begin the text. Finally,
+// we look to see that the remaining characters are only whitespace or ']' or
+// ',' or ':' or '{' or '}'. If that is so, then the text is safe for eval.
+
+ if (/^[\],:{}\s]*$/.test(text.replace(/\\./g, '@').
+replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(:?[eE][+\-]?\d+)?/g, ']').
+replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) {
+
+// In the second stage we use the eval function to compile the text into a
+// JavaScript structure. The '{' operator is subject to a syntactic ambiguity
+// in JavaScript: it can begin a block or an object literal. We wrap the text
+// in parens to eliminate the ambiguity.
+
+ j = eval('(' + text + ')');
+
+// In the optional third stage, we recursively walk the new structure, passing
+// each name/value pair to a filter function for possible transformation.
+
+ return typeof filter === 'function' ? walk('', j) : j;
+ }
+
+// If the text is not JSON parseable, then a SyntaxError is thrown.
+
+ throw new SyntaxError('parseJSON');
+ }
+ };
+ }();
+}
Added: trunk/examples/RestYUI/root/static/sprite.png
===================================================================
(Binary files differ)
Property changes on: trunk/examples/RestYUI/root/static/sprite.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/examples/RestYUI/root/user/single_user.tt
===================================================================
--- trunk/examples/RestYUI/root/user/single_user.tt (rev 0)
+++ trunk/examples/RestYUI/root/user/single_user.tt 2007-12-02 17:26:05 UTC (rev 7200)
@@ -0,0 +1,85 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
+<head>
+ <title>REST User: [% rest.fullname || rest.error %]</title>
+ <script type="text/javascript" src="/static/yui/yahoo.js"></script>
+ <script type="text/javascript" src="/static/yui/event.js"></script>
+ <script type="text/javascript" src="/static/yui/utilities.js"></script>
+ <script type="text/javascript" src="/static/yui/connection.js"></script>
+ <script type="text/javascript" src="/static/yui/dom.js"></script>
+ <script type="text/javascript" src="/static/json2.js"></script>
+</head>
+<body>
+ [%
+ SET method = 'PUT';
+ # Editing an existing user?
+ IF rest.user_id;
+ # Set the method to POST
+ method = 'POST';
+ END;
+ %]
+ <form id="user_form">
+ <p>
+ <label for="user_id">User ID:</label>
+ <input id="user_id" type="text" disabled="disabled" value="[% c.req.args.0 %]"/>
+ </p><p>
+ <label for="fullname">Full Name:</label>
+ <input id="fullname" type="text" value="[% rest.fullname %]"/>
+ </p><p>
+ <label for="Description">Description:</label><br/>
+ <textarea name="description">[% rest.description %]</textarea>
+ </p><p>
+ <input type="submit" value="[% method == 'PUT' ? "Create User" : "Update User" %]"/>
+ </p>
+ </form>
+ <script type="text/javascript">
+ var handleSuccess = function(o) {
+ /* Object Created, check for Loc header */
+ if ( o.status == "201" ) {
+ var loc = o.getResponseHeader["Location"];
+ if ( loc ) {
+ document.location = loc;
+ return true;
+ }
+ /* Just refresh if we did not get a location
+ */
+ alert("Object was created successfully");
+ document.location = document.location;
+ } else if ( o.status == "200" ) {
+ alert("User Update OK");
+ }
+ };
+
+ var handleFailure = function(o) {
+ alert("Failed! :(\n" + o.responseText);
+ }
+
+ YAHOO.util.Event.addListener(window, "load", function() {
+ var callback = {
+ success: handleSuccess,
+ failure: handleFailure
+ };
+ var form = YAHOO.util.Dom.get("user_form");
+ YAHOO.util.Event.addListener(form, "submit", function(e) {
+ YAHOO.util.Event.preventDefault(e);
+ window.setTimeout(function() {
+ var uri = '[% c.req.uri %]';
+
+ var data = {
+ user_id: form['user_id'].value,
+ fullname: form['fullname'].value,
+ description: form['description'].value
+ };
+ YAHOO.util.Connect.setDefaultPostHeader('text/x-json');
+ var request = YAHOO.util.Connect.asyncRequest(
+ '[% method %]',
+ uri,
+ callback,
+ JSON.stringify(data)
+ );
+ }, 200);
+ });
+ });
+ </script>
+</body>
+</html>
More information about the Catalyst-commits
mailing list