You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cordova.apache.org by an...@apache.org on 2013/10/22 01:24:24 UTC
[4/9] first commit
http://git-wip-us.apache.org/repos/asf/cordova-registry-web/blob/f50cc931/attachments/layout.less
----------------------------------------------------------------------
diff --git a/attachments/layout.less b/attachments/layout.less
new file mode 100644
index 0000000..1ccef0a
--- /dev/null
+++ b/attachments/layout.less
@@ -0,0 +1,461 @@
+/* ----- mixins ------ */
+
+.border-radius( @radius: 8px ) {
+ -moz-border-radius: @radius;
+ -webkit-border-radius: @radius;
+ border-radius: @radius;
+}
+
+.transition ( @type: all, @sec: 0.25s ) {
+ -webkit-transition: @type @sec linear;
+ -moz-transition: @type @sec linear;
+ transition: @type @sec linear;
+}
+
+@highlight-color: #4cc2e4;
+@font-color: #3b4854;
+
+@import "font/style.css";
+
+/* ----- font ----- */
+
+html {
+ font-size: 17px;
+ font-family: 'HelveticaNeue-Light', Helvetica, Arial, sans-serif;
+ color: @font-color;
+}
+
+h1 {
+ font-size: 1.8em;
+ font-weight: normal;
+}
+
+h2 {
+ font-size: 1.2em;
+ font-weight: normal;
+}
+
+
+/* ----- basic layout ----- */
+
+body {
+ background: #fff;
+ margin: 0;
+}
+
+.wrap, #tabs {
+ max-width: 1000px;
+ margin: 0 auto;
+ padding: 40px 0;
+}
+
+.grid {
+ background: url(images/grid.png);
+}
+
+
+/* ----- common elements -----*/
+
+a {
+ color: @highlight-color;
+ text-decoration:none;
+}
+
+a.dep-link {
+ padding-right:7px;
+}
+
+.spacer, .clear {
+ clear:both;
+}
+
+.button {
+ display: inline-block;
+ background-color: @highlight-color;
+ margin-left: 8px;
+ padding: 10px 16px;
+ color: #fff;
+ font-size: 1.5em;
+ text-align: center;
+ text-decoration: none;
+ .transition( background );
+ border-bottom: 4px solid darken(@highlight-color,10%);
+
+ &:hover {
+ background-color: #4cd6fc;
+ color: #fff;
+ }
+}
+
+
+/* ----- header ---- */
+
+#header {
+ text-align: left;
+ border-bottom: 3px solid rgba(0,0,0,0.1);
+ position: relative;
+ z-index: 3;
+ margin-bottom: -3px;
+
+ .wrap {
+ padding: 20px 0;
+ }
+
+ a {
+ .transition( color );
+ color: @font-color;
+ display: inline-block;
+ padding: 6px 0;
+ position: relative;
+
+ &:hover {
+ color: @highlight-color;
+ }
+ }
+
+ a.logo {
+ padding-left: 40px;
+ font-size: 1.2em;
+
+ &:before {
+ font-size: 1.5em;
+ position: absolute;
+ left: 0;
+ top: 3px;
+ }
+ }
+
+ #howto {
+ float: right;
+
+ a {
+ padding-top: 10px;
+ margin-left: 24px;
+
+ span {
+ position: absolute;
+ top: -0px;
+ left: 0;
+ font-size: 10px;
+ font-weight: 600;
+ }
+ }
+ }
+}
+
+
+/* ----- content ---- */
+
+#content-wrapper {
+ padding-top: 0;
+}
+
+
+#content,
+#tabs a, #tabs span {
+ background: #fff;
+ padding: 2% 2%;
+ .border-radius( 5px );
+ position: relative;
+}
+
+#content {
+ padding: 4% 2%;
+}
+
+#tabs {
+ margin-bottom: -7px;
+ padding-bottom: 0;
+
+ a, span {
+ display: inline-block;
+ padding: 16px 20px 18px;
+ margin: 0 10px 0 0;
+ }
+
+ a {
+ .transition( background-color );
+ background-color: @highlight-color;
+ color: #fff;
+
+ &:hover {
+ background-color: lighten( @highlight-color, 10% );
+ }
+
+ &.selected {
+ background-color: #fff;
+ color: @font-color;
+ &:hover {
+ background-color: #fff;
+ }
+ }
+ }
+}
+
+#search-box {
+ width: auto;
+ margin-bottom: 20px;
+}
+
+#search-box-input {
+ span {
+ line-height: 60px;
+ width: 5%;
+ font-size: 1.5em;
+ font-weight: bold;
+ text-align: center;
+ float: left;
+ }
+
+ .button {
+ padding-left: 2%;
+ padding-right: 2%;
+ width: 25%;
+ float: left;
+ }
+}
+
+#search-input {
+ width: auto;
+ min-width: 90%;
+ font-size: 1.5em;
+ padding: 10px 2%;
+ border: none;
+ font-weight: normal;
+ margin: 0 8px 0 0;
+ border: 1px solid #ddd;
+ border-top: 4px #ddd solid;
+ // float: left;
+
+ &:focus {
+ outline-color: @highlight-color;
+ }
+}
+
+#browse-anchors {
+
+ a {
+ margin-right:20px;
+ padding: 3px 5px 3px 5px;
+ background-color: #fff;
+
+ display: inline-block;
+ background-color: @highlight-color;
+ margin-right: 8px;
+ padding: 4px 12px;
+ color: #fff;
+ text-align: center;
+ text-decoration: none;
+ .transition( background );
+ border-bottom: 2px solid darken(@highlight-color,10%);
+
+ &:hover {
+ background-color: #4cd6fc;
+ color: #fff;
+ }
+ }
+}
+
+
+// #main-container, #search-box,
+
+
+
+
+/* ----- footer ---- */
+
+#footer {
+ height:40px;
+}
+
+
+/* ----- everything else ----- */
+
+div#results {
+ font-size:20px;
+ width:100%;
+ padding-top:4px;
+}
+div.result {
+ width:100%;
+}
+div.result-container {
+ padding-bottom:6px;
+}
+span.result-name {
+ padding-right:10px;
+}
+span.result-desc {
+ color:#6B6B6B;
+}
+div.result-tags {
+ text-align:right;
+ font-size:16px;
+ padding-right:4px;
+ float:right;
+}
+span.tag {
+ padding-left:6px;
+ cursor:pointer;
+ color:#878787;
+}
+span.desc-term {
+ color:#141414;
+}
+div.package {
+ text-align:center;
+}
+
+div.package-title {
+ font-size:45px;
+ float:left;
+}
+div.pkg-link {
+ float:left;
+ padding-top:20px;
+ margin-left:30px;
+}
+
+div#latest-packages {
+ width:45%;
+ float:left;
+ margin-right: 5%;
+}
+
+div#top-dep-packages {
+ width:45%;
+ margin-left:5%;
+ float:left;
+}
+
+div.top-title {
+ text-align:center;
+}
+
+div.top-package {
+ width:100%;
+}
+div.top-package-title {
+ padding-right:7px;
+ float:left;
+}
+div.top-package-updated {
+ float:right;
+ text-align:right;
+ padding-right:15px;
+}
+div.top-package-dep {
+ float:right;
+ text-align:right;
+ padding-right:15px;
+}
+
+div.dependencies {
+ width:80%;
+ text-align:left;
+ padding-left:10%;
+ padding-right:10%;
+}
+div.users {
+ width:80%;
+ text-align:left;
+ padding-left:10%;
+ padding-right:10%;
+}
+a.dep {
+ margin-right:10px;
+}
+a.user {
+ margin-right:10px;
+}
+div#totals {
+ float:right;
+ position:absolute;
+ top:10px;
+ right:10px;
+}
+div.all-package {
+ width:100%;
+}
+div.all-package-name {
+ width:40%;
+ padding-right:2%;
+ float:left;
+}
+div.all-package-desc {
+ width:50%;
+ float:left;
+}
+div#more-all {
+ cursor:pointer;
+ color:blue;
+}
+
+div#versions-container {
+ margin-top:10px;
+ width:100%;
+}
+div#version-list {
+ float:left;
+ width:20%;
+}
+div#version-info {
+ float:left;
+ width:78%;
+ background-color:#B9D3EE;
+ padding: 1% 1% 1% 1%;
+}
+div.version-info-cell {
+ width:100%;
+}
+div.version-info-key {
+ float:left;
+}
+div.version-info-value {
+ float:right;
+ text-align:right;
+}
+div.version-selected {
+ background-color:#B9D3EE;
+}
+div.version-link {
+ width:100%;
+ padding: 3px 0px 0px 10px;
+}
+
+span.expand-tags {
+ padding-left:10px;
+ font-size:12px;
+ cursor:pointer;
+ color:#FF1D4E;
+}
+a.tag-val {
+ padding-right:10px;
+ padding-left:5px;
+}
+div.all-package-author {
+ width:30%;
+ float:left;
+}
+
+div.all-package-auth-list {
+ width:70%;
+ float:left;
+}
+div.all-package-deps {
+ width:50%;
+ float:left;
+}
+div.all-package-deps-value {
+ width:50%;
+ float:left;
+}
+div.tags-pkg-name {
+ float:left;
+ width:30%;
+ font-size:30px;
+}
+div.tags-pkg-desc {
+ float:left;
+ width:70%;
+}
http://git-wip-us.apache.org/repos/asf/cordova-registry-web/blob/f50cc931/attachments/more.html
----------------------------------------------------------------------
diff --git a/attachments/more.html b/attachments/more.html
new file mode 100644
index 0000000..c6fa383
--- /dev/null
+++ b/attachments/more.html
@@ -0,0 +1,3 @@
+<h2>Goodies</h2>
+
+<h3><a href="/#/_analytics">Analytics</a></div>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/cordova-registry-web/blob/f50cc931/attachments/publish.html
----------------------------------------------------------------------
diff --git a/attachments/publish.html b/attachments/publish.html
new file mode 100644
index 0000000..e69de29
http://git-wip-us.apache.org/repos/asf/cordova-registry-web/blob/f50cc931/attachments/sammy/plugins/sammy.cache.js
----------------------------------------------------------------------
diff --git a/attachments/sammy/plugins/sammy.cache.js b/attachments/sammy/plugins/sammy.cache.js
new file mode 100644
index 0000000..b2622c8
--- /dev/null
+++ b/attachments/sammy/plugins/sammy.cache.js
@@ -0,0 +1,115 @@
+// deprecated
+(function($) {
+
+ Sammy = Sammy || {};
+
+ // A simple cache strategy that stores key/values in memory.
+ Sammy.MemoryCacheProxy = function(initial) {
+ this._cache = initial || {};
+ };
+
+ $.extend(Sammy.MemoryCacheProxy.prototype, {
+ exists: function(name) {
+ return (typeof this._cache[name] != "undefined");
+ },
+ set: function(name, value) {
+ return this._cache[name] = value;
+ },
+ get: function(name) {
+ return this._cache[name];
+ },
+ clear: function(name) {
+ delete this._cache[name];
+ }
+ });
+
+ // A simple cache strategy that stores key/values <tt>$element.data()</tt> with a <tt>cache.</tt> prefix
+ Sammy.DataCacheProxy = function(initial, $element) {
+ initial = initial || {};
+ this.$element = $element;
+ $.each(initial, function(key, value) {
+ $element.data('cache.' + key, value);
+ });
+ };
+
+ $.extend(Sammy.DataCacheProxy.prototype, {
+ exists: function(name) {
+ return (typeof this.$element.data('cache.' + name) != "undefined");
+ },
+ set: function(name, value) {
+ return this.$element.data('cache.' + name, value);
+ },
+ get: function(name) {
+ return this.$element.data('cache.' + name);
+ },
+ clear: function(name) {
+ this.$element.removeData('cache.' + name);
+ }
+ });
+
+ // Sammy.Cache provides helpers for caching data within the lifecycle of a
+ // Sammy app. The plugin provides two main methods on <tt>Sammy.Application<tt>,
+ // <tt>cache</tt> and <tt>clearCache</tt>. Each app has its own cache store so that
+ // you dont have to worry about collisions. There are currently two different 'cache proxies'
+ // that share the same API but store the data in different ways.
+ //
+ // ### Arguments
+ //
+ // * `proxy` decides which caching proxy to use, either 'memory'(default) or 'data'
+ //
+ Sammy.Cache = function(app, proxy) {
+
+ app.log('**WARNING:** This version of Sammy.Cache has been deprecated in favor of using the version in Sammy.Storage and will be removed in 1.0')
+
+ if (proxy == 'data') {
+ this.cache_proxy = new Sammy.DataCacheProxy({}, this.$element());
+ } else {
+ this.cache_proxy = new Sammy.MemoryCacheProxy({});
+ }
+
+ app.cache_partials = true;
+
+ $.extend(app, {
+ // cache is the main method for interacting with the cache store. The same
+ // method is used for both setting and getting the value. The API is similar
+ // to jQuery.fn.attr()
+ //
+ // ### Examples
+ //
+ // // setting a value
+ // cache('key', 'value');
+ //
+ // // getting a value
+ // cache('key'); //=> 'value'
+ //
+ // // setting a value with a callback
+ // cache('key', function() {
+ // // this is the app
+ // return app.element_selector;
+ // });
+ //
+ cache: function(name, value) {
+ if (typeof value == 'undefined') {
+ return this.cache_proxy.get(name);
+ } else if ($.isFunction(value) && !this.cache_proxy.exists(name)) {
+ return this.cache_proxy.set(name, value.apply(this));
+ } else {
+ return this.cache_proxy.set(name, value)
+ }
+ },
+
+ // clears the cached value for <tt>name</tt>
+ clearCache: function(name) {
+ return this.cache_proxy.clear(name);
+ }
+ });
+
+ app.helpers({
+ // a helper shortcut for use in <tt>Sammy.EventContext</tt>
+ cache: function(name, value) {
+ return this.app.cache(name, value);
+ }
+ });
+ };
+
+})(jQuery);
http://git-wip-us.apache.org/repos/asf/cordova-registry-web/blob/f50cc931/attachments/sammy/plugins/sammy.data_location_proxy.js
----------------------------------------------------------------------
diff --git a/attachments/sammy/plugins/sammy.data_location_proxy.js b/attachments/sammy/plugins/sammy.data_location_proxy.js
new file mode 100644
index 0000000..6b0ada3
--- /dev/null
+++ b/attachments/sammy/plugins/sammy.data_location_proxy.js
@@ -0,0 +1,78 @@
+(function($) {
+
+ Sammy = Sammy || {};
+
+ // The DataLocationProxy is an optional location proxy prototype. As opposed to
+ // the `HashLocationProxy` it gets its location from a jQuery.data attribute
+ // tied to the application's element. You can set the name of the attribute by
+ // passing a string as the second argument to the constructor. The default attribute
+ // name is 'sammy-location'. To read more about location proxies, check out the
+ // documentation for `Sammy.HashLocationProxy`
+ //
+ // An optional `href_attribute` can be passed, which specifies a DOM element
+ // attribute that holds "links" to different locations in the app. When the
+ // proxy is bound, clicks to element that have this attribute activate a
+ // `setLocation()` using the contents of the `href_attribute`.
+ //
+ // ### Example
+ //
+ // var app = $.sammy(function() {
+ // // set up the location proxy
+ // this.setLocationProxy(new Sammy.DataLocationProxy(this, 'location', 'rel'));
+ //
+ // this.get('about', function() {
+ // this.partial('about.html');
+ // });
+ //
+ // });
+ //
+ // In this scenario, if an element existed within the template:
+ //
+ // <a href="/about" rel="about">About Us</a>
+ //
+ // Clicking on that link would not go to /about, but would set the apps location
+ // to 'about' and trigger the route.
+ Sammy.DataLocationProxy = function(app, data_name, href_attribute) {
+ this.app = app;
+ this.data_name = data_name || 'sammy-location';
+ this.href_attribute = href_attribute;
+ };
+
+ Sammy.DataLocationProxy.prototype = {
+ bind: function() {
+ var proxy = this;
+ this.app.$element().bind('setData', function(e, key, value) {
+ if (key == proxy.data_name) {
+ // jQuery unfortunately fires the event before it sets the value
+ // work around it, by setting the value ourselves
+ proxy.app.$element().each(function() {
+ $.data(this, proxy.data_name, value);
+ });
+ proxy.app.trigger('location-changed');
+ }
+ });
+ if (this.href_attribute) {
+ this.app.$element().delegate('[' + this.href_attribute + ']', 'click', function(e) {
+ e.preventDefault();
+ proxy.setLocation($(this).attr(proxy.href_attribute));
+ });
+ }
+ },
+
+ unbind: function() {
+ if (this.href_attribute) {
+ this.app.$element().undelegate('[' + this.href_attribute + ']', 'click');
+ }
+ this.app.$element().unbind('setData');
+ },
+
+ getLocation: function() {
+ return this.app.$element().data(this.data_name);
+ },
+
+ setLocation: function(new_location) {
+ return this.app.$element().data(this.data_name, new_location);
+ }
+ };
+
+})(jQuery);
http://git-wip-us.apache.org/repos/asf/cordova-registry-web/blob/f50cc931/attachments/sammy/plugins/sammy.ejs.js
----------------------------------------------------------------------
diff --git a/attachments/sammy/plugins/sammy.ejs.js b/attachments/sammy/plugins/sammy.ejs.js
new file mode 100644
index 0000000..4fb7493
--- /dev/null
+++ b/attachments/sammy/plugins/sammy.ejs.js
@@ -0,0 +1,700 @@
+(function($) {
+
+ // Embeddedjs is property of http://embeddedjs.com/
+ // Sammy ejs plugin written Codeofficer @ http://www.codeofficer.com/
+
+ var rsplit = function(string, regex) {
+ var result = regex.exec(string),
+ retArr = new Array(),
+ first_idx, last_idx, first_bit;
+ while (result != null) {
+ first_idx = result.index;
+ last_idx = regex.lastIndex;
+ if ((first_idx) != 0) {
+ first_bit = string.substring(0, first_idx);
+ retArr.push(string.substring(0, first_idx));
+ string = string.slice(first_idx);
+ };
+ retArr.push(result[0]);
+ string = string.slice(result[0].length);
+ result = regex.exec(string);
+ };
+ if (! string == '') {
+ retArr.push(string);
+ };
+ return retArr;
+ };
+
+ var chop = function(string) {
+ return string.substr(0, string.length - 1);
+ };
+
+ var extend = function(d, s) {
+ for (var n in s) {
+ if(s.hasOwnProperty(n)) d[n] = s[n];
+ };
+ };
+
+ /* @Constructor*/
+ EJS = function(options) {
+ options = (typeof(options) == "string") ? {view: options} : options;
+ this.set_options(options);
+ if (options.precompiled) {
+ this.template = {};
+ this.template.process = options.precompiled;
+ EJS.update(this.name, this);
+ return;
+ };
+ if (options.element) {
+ if (typeof(options.element) == 'string') {
+ var name = options.element;
+ options.element = document.getElementById(options.element);
+ if (options.element == null) throw name + 'does not exist!';
+ };
+ if (options.element.value) {
+ this.text = options.element.value;
+ } else {
+ this.text = options.element.innerHTML;
+ };
+ this.name = options.element.id;
+ this.type = '[';
+ } else if (options.url) {
+ options.url = EJS.endExt(options.url, this.extMatch);
+ this.name = this.name ? this.name : options.url;
+ var url = options.url;
+ //options.view = options.absolute_url || options.view || options.;
+ var template = EJS.get(this.name /*url*/, this.cache);
+ if (template) return template;
+ if (template == EJS.INVALID_PATH) return null;
+ try {
+ this.text = EJS.request( url + (this.cache ? '' : '?' + Math.random() ));
+ } catch(e) {};
+ if (this.text == null) {
+ throw( {type: 'EJS', message: 'There is no template at '+url} );
+ };
+ //this.name = url;
+ };
+ var template = new EJS.Compiler(this.text, this.type);
+ template.compile(options, this.name);
+ EJS.update(this.name, this);
+ this.template = template;
+ };
+
+ /* @Prototype*/
+ EJS.prototype = {
+ /**
+ * Renders an object with extra view helpers attached to the view.
+ * @param {Object} object data to be rendered
+ * @param {Object} extra_helpers an object with additonal view helpers
+ * @return {String} returns the result of the string
+ */
+ render : function(object, extra_helpers) {
+ object = object || {};
+ this._extra_helpers = extra_helpers;
+ var v = new EJS.Helpers(object, extra_helpers || {});
+ return this.template.process.call(object, object,v);
+ },
+
+ update : function(element, options) {
+ if (typeof(element) == 'string') {
+ element = document.getElementById(element);
+ };
+ if (options == null) {
+ _template = this;
+ return function(object) {
+ EJS.prototype.update.call(_template, element, object);
+ };
+ };
+ if (typeof(options) == 'string') {
+ params = {};
+ params.url = options;
+ _template = this;
+ params.onComplete = function(request) {
+ var object = eval(request.responseText);
+ EJS.prototype.update.call(_template, element, object);
+ };
+ EJS.ajax_request(params);
+ } else {
+ element.innerHTML = this.render(options);
+ };
+ },
+
+ out : function() {
+ return this.template.out;
+ },
+
+ /**
+ * Sets options on this view to be rendered with.
+ * @param {Object} options
+ */
+ set_options : function(options){
+ this.type = options.type || EJS.type;
+ this.cache = (options.cache != null) ? options.cache : EJS.cache;
+ this.text = options.text || null;
+ this.name = options.name || null;
+ this.ext = options.ext || EJS.ext;
+ this.extMatch = new RegExp(this.ext.replace(/\./, '\.'));
+ }
+ };
+
+ EJS.endExt = function(path, match) {
+ if (!path) return null;
+ match.lastIndex = 0;
+ return path + (match.test(path) ? '' : this.ext);
+ };
+
+ /* @Static*/
+ EJS.Scanner = function(source, left, right) {
+ extend(this, {
+ left_delimiter: left +'%',
+ right_delimiter: '%'+right,
+ double_left: left+'%%',
+ double_right: '%%'+right,
+ left_equal: left+'%=',
+ left_comment: left+'%#'
+ });
+ this.SplitRegexp = (left == '[') ? /(\[%%)|(%%\])|(\[%=)|(\[%#)|(\[%)|(%\]\n)|(%\])|(\n)/ : new RegExp('('+this.double_left+')|(%%'+this.double_right+')|('+this.left_equal+')|('+this.left_comment+')|('+this.left_delimiter+')|('+this.right_delimiter+'\n)|('+this.right_delimiter+')|(\n)');
+ this.source = source;
+ this.stag = null;
+ this.lines = 0;
+ };
+
+ EJS.Scanner.to_text = function(input) {
+ if (input == null || input === undefined) return '';
+ if(input instanceof Date) return input.toDateString();
+ if(input.toString) return input.toString();
+ return '';
+ };
+
+ EJS.Scanner.prototype = {
+ scan: function(block) {
+ scanline = this.scanline;
+ regex = this.SplitRegexp;
+ if (! this.source == '') {
+ var source_split = rsplit(this.source, /\n/);
+ for (var i=0; i<source_split.length; i++) {
+ var item = source_split[i];
+ this.scanline(item, regex, block);
+ };
+ };
+ },
+
+ scanline: function(line, regex, block) {
+ this.lines++;
+ var line_split = rsplit(line, regex);
+ for (var i=0; i<line_split.length; i++) {
+ var token = line_split[i];
+ if (token != null) {
+ try {
+ block(token, this);
+ } catch(e) {
+ throw {type: 'EJS.Scanner', line: this.lines};
+ };
+ };
+ };
+ }
+ };
+
+ EJS.Buffer = function(pre_cmd, post_cmd) {
+ this.line = new Array();
+ this.script = "";
+ this.pre_cmd = pre_cmd;
+ this.post_cmd = post_cmd;
+ for (var i=0; i<this.pre_cmd.length; i++) {
+ this.push(pre_cmd[i]);
+ };
+ };
+
+ EJS.Buffer.prototype = {
+ push: function(cmd) {
+ this.line.push(cmd);
+ },
+
+ cr: function() {
+ this.script = this.script + this.line.join('; ');
+ this.line = new Array();
+ this.script = this.script + "\n";
+ },
+
+ close: function() {
+ if (this.line.length > 0) {
+ for (var i=0; i<this.post_cmd.length; i++){
+ this.push(pre_cmd[i]);
+ };
+ this.script = this.script + this.line.join('; ');
+ line = null;
+ };
+ }
+ };
+
+ EJS.Compiler = function(source, left) {
+ this.pre_cmd = ['var ___ViewO = [];'];
+ this.post_cmd = new Array();
+ this.source = ' ';
+ if (source != null) {
+ if (typeof(source) == 'string') {
+ source = source.replace(/\r\n/g, "\n");
+ source = source.replace(/\r/g, "\n");
+ this.source = source;
+ } else if (source.innerHTML) {
+ this.source = source.innerHTML;
+ };
+ if (typeof this.source != 'string') {
+ this.source = "";
+ };
+ };
+ left = left || '<';
+ var right = '>';
+ switch(left) {
+ case '[':
+ right = ']';
+ break;
+ case '<':
+ break;
+ default:
+ throw left+' is not a supported deliminator';
+ break;
+ };
+ this.scanner = new EJS.Scanner(this.source, left, right);
+ this.out = '';
+ };
+
+ EJS.Compiler.prototype = {
+ compile: function(options, name) {
+ options = options || {};
+ this.out = '';
+ var put_cmd = "___ViewO.push(";
+ var insert_cmd = put_cmd;
+ var buff = new EJS.Buffer(this.pre_cmd, this.post_cmd);
+ var content = '';
+ var clean = function(content) {
+ content = content.replace(/\\/g, '\\\\');
+ content = content.replace(/\n/g, '\\n');
+ content = content.replace(/"/g, '\\"');
+ return content;
+ };
+ this.scanner.scan(function(token, scanner) {
+ if (scanner.stag == null) {
+ switch(token) {
+ case '\n':
+ content = content + "\n";
+ buff.push(put_cmd + '"' + clean(content) + '");');
+ buff.cr();
+ content = '';
+ break;
+ case scanner.left_delimiter:
+ case scanner.left_equal:
+ case scanner.left_comment:
+ scanner.stag = token;
+ if (content.length > 0) {
+ buff.push(put_cmd + '"' + clean(content) + '")');
+ };
+ content = '';
+ break;
+ case scanner.double_left:
+ content = content + scanner.left_delimiter;
+ break;
+ default:
+ content = content + token;
+ break;
+ };
+ } else {
+ switch(token) {
+ case scanner.right_delimiter:
+ switch(scanner.stag) {
+ case scanner.left_delimiter:
+ if (content[content.length - 1] == '\n') {
+ content = chop(content);
+ buff.push(content);
+ buff.cr();
+ } else {
+ buff.push(content);
+ };
+ break;
+ case scanner.left_equal:
+ buff.push(insert_cmd + "(EJS.Scanner.to_text(" + content + ")))");
+ break;
+ };
+ scanner.stag = null;
+ content = '';
+ break;
+ case scanner.double_right:
+ content = content + scanner.right_delimiter;
+ break;
+ default:
+ content = content + token;
+ break;
+ };
+ };
+ });
+ if (content.length > 0) {
+ // Chould be content.dump in Ruby
+ buff.push(put_cmd + '"' + clean(content) + '")');
+ };
+ buff.close();
+ this.out = buff.script + ";";
+ var to_be_evaled = '/*' + name + '*/this.process = function(_CONTEXT,_VIEW) { try { with(_VIEW) { with (_CONTEXT) {' + this.out + " return ___ViewO.join('');}}}catch(e){e.lineNumber=null;throw e;}};";
+ try {
+ eval(to_be_evaled);
+ } catch(e) {
+ if (typeof JSLINT != 'undefined') {
+ JSLINT(this.out);
+ for (var i = 0; i < JSLINT.errors.length; i++) {
+ var error = JSLINT.errors[i];
+ if (error.reason != "Unnecessary semicolon.") {
+ error.line++;
+ var e = new Error();
+ e.lineNumber = error.line;
+ e.message = error.reason;
+ if (options.view) e.fileName = options.view;
+ throw e;
+ };
+ };
+ } else {
+ throw e;
+ };
+ };
+ }
+ };
+
+ //type, cache, folder
+ /**
+ * Sets default options for all views
+ * @param {Object} options Set view with the following options
+ * <table class="options">
+ <tbody><tr><th>Option</th><th>Default</th><th>Description</th></tr>
+ <tr>
+ <td>type</td>
+ <td>'<'</td>
+ <td>type of magic tags. Options are '<' or '['
+ </td>
+ </tr>
+ <tr>
+ <td>cache</td>
+ <td>true in production mode, false in other modes</td>
+ <td>true to cache template.
+ </td>
+ </tr>
+ </tbody></table>
+ *
+ */
+ EJS.config = function(options){
+ EJS.cache = (options.cache != null) ? options.cache : EJS.cache;
+ EJS.type = (options.type != null) ? options.type : EJS.type;
+ EJS.ext = (options.ext != null) ? options.ext : EJS.ext;
+ var templates_directory = EJS.templates_directory || {}; //nice and private container
+ EJS.templates_directory = templates_directory;
+ EJS.get = function(path, cache) {
+ if(cache == false) return null;
+ if(templates_directory[path]) return templates_directory[path];
+ return null;
+ };
+ EJS.update = function(path, template) {
+ if (path == null) return;
+ templates_directory[path] = template ;
+ };
+ EJS.INVALID_PATH = -1;
+ };
+ EJS.config( {cache: true, type: '<', ext: '.ejs' } );
+
+ /**
+ * @constructor
+ * By adding functions to EJS.Helpers.prototype, those functions will be available in the
+ * views.
+ * @init Creates a view helper. This function is called internally. You should never call it.
+ * @param {Object} data The data passed to the view. Helpers have access to it through this._data
+ */
+ EJS.Helpers = function(data, extras){
+ this._data = data;
+ this._extras = extras;
+ extend(this, extras);
+ };
+
+ /* @prototype*/
+ EJS.Helpers.prototype = {
+ /**
+ * Renders a new view. If data is passed in, uses that to render the view.
+ * @param {Object} options standard options passed to a new view.
+ * @param {optional:Object} data
+ * @return {String}
+ */
+ view: function(options, data, helpers) {
+ if (!helpers) helpers = this._extras;
+ if (!data) data = this._data;
+ return new EJS(options).render(data, helpers);
+ },
+ /**
+ * For a given value, tries to create a human representation.
+ * @param {Object} input the value being converted.
+ * @param {Object} null_text what text should be present if input == null or undefined, defaults to ''
+ * @return {String}
+ */
+ to_text: function(input, null_text) {
+ if (input == null || input === undefined) return null_text || '';
+ if (input instanceof(Date)) return input.toDateString();
+ if (input.toString) return input.toString().replace(/\n/g, '<br />').replace(/''/g, "'");
+ return '';
+ }
+ };
+
+ EJS.newRequest = function() {
+ var factories = [function() { return new ActiveXObject("Msxml2.XMLHTTP"); },function() { return new XMLHttpRequest(); },function() { return new ActiveXObject("Microsoft.XMLHTTP"); }];
+ for(var i = 0; i < factories.length; i++) {
+ try {
+ var request = factories[i]();
+ if (request != null) return request;
+ } catch(e) { continue; }
+ };
+ };
+
+ EJS.request = function(path) {
+ var request = new EJS.newRequest();
+ request.open("GET", path, false);
+ try {
+ request.send(null);
+ } catch(e){
+ return null;
+ };
+ if ( request.status == 404 || request.status == 2 ||(request.status == 0 && request.responseText == '') ) return null;
+ return request.responseText;
+ };
+
+ EJS.ajax_request = function(params) {
+ params.method = ( params.method ? params.method : 'GET');
+ var request = new EJS.newRequest();
+ request.onreadystatechange = function() {
+ if (request.readyState == 4) {
+ if (request.status == 200) {
+ params.onComplete(request);
+ } else {
+ params.onComplete(request);
+ };
+ };
+ };
+ request.open(params.method, params.url);
+ request.send(null);
+ };
+
+ EJS.Helpers.prototype.date_tag = function(name, value , html_options) {
+ if(!(value instanceof(Date))) value = new Date();
+ var month_names = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
+ var years = [], months = [], days =[];
+ var year = value.getFullYear();
+ var month = value.getMonth();
+ var day = value.getDate();
+ for (var y = year - 15; y < year+15 ; y++) {
+ years.push({value: y, text: y});
+ };
+ for (var m = 0; m < 12; m++) {
+ months.push({value: (m), text: month_names[m]});
+ };
+ for (var d = 0; d < 31; d++) {
+ days.push({value: (d+1), text: (d+1)});
+ };
+ var year_select = this.select_tag(name+'[year]', year, years, {id: name+'[year]'} );
+ var month_select = this.select_tag(name+'[month]', month, months, {id: name+'[month]'});
+ var day_select = this.select_tag(name+'[day]', day, days, {id: name+'[day]'});
+ return year_select+month_select+day_select;
+ };
+
+ EJS.Helpers.prototype.form_tag = function(action, html_options) {
+ html_options = html_options || {};
+ html_options.action = action;
+ if(html_options.multipart == true) {
+ html_options.method = 'post';
+ html_options.enctype = 'multipart/form-data';
+ };
+ return this.start_tag_for('form', html_options);
+ };
+
+ EJS.Helpers.prototype.form_tag_end = function() {
+ return this.tag_end('form');
+ };
+
+ EJS.Helpers.prototype.hidden_field_tag = function(name, value, html_options) {
+ return this.input_field_tag(name, value, 'hidden', html_options);
+ };
+
+ EJS.Helpers.prototype.input_field_tag = function(name, value , inputType, html_options) {
+ html_options = html_options || {};
+ html_options.id = html_options.id || name;
+ html_options.value = value || '';
+ html_options.type = inputType || 'text';
+ html_options.name = name;
+ return this.single_tag_for('input', html_options);
+ };
+
+ EJS.Helpers.prototype.is_current_page = function(url) {
+ return (window.location.href == url || window.location.pathname == url ? true : false);
+ };
+
+ EJS.Helpers.prototype.link_to = function(name, url, html_options) {
+ if(!name) var name = 'null';
+ if(!html_options) var html_options = {};
+ if(html_options.confirm){
+ html_options.onclick = " var ret_confirm = confirm(\""+html_options.confirm+"\"); if(!ret_confirm){ return false;} ";
+ html_options.confirm = null;
+ };
+ html_options.href = url;
+ return this.start_tag_for('a', html_options)+name+ this.tag_end('a');
+ };
+
+ EJS.Helpers.prototype.submit_link_to = function(name, url, html_options) {
+ if(!name) var name = 'null';
+ if(!html_options) var html_options = {};
+ html_options.onclick = html_options.onclick || '';
+ if(html_options.confirm){
+ html_options.onclick = " var ret_confirm = confirm(\""+html_options.confirm+"\"); if(!ret_confirm){ return false;} ";
+ html_options.confirm = null;
+ };
+ html_options.value = name;
+ html_options.type = 'submit';
+ html_options.onclick = html_options.onclick + (url ? this.url_for(url) : '')+'return false;';
+ return this.start_tag_for('input', html_options);
+ };
+
+ EJS.Helpers.prototype.link_to_if = function(condition, name, url, html_options, post, block) {
+ return this.link_to_unless((condition == false), name, url, html_options, post, block);
+ };
+
+ EJS.Helpers.prototype.link_to_unless = function(condition, name, url, html_options, block) {
+ html_options = html_options || {};
+ if(condition) {
+ if(block && typeof(block) == 'function') {
+ return block(name, url, html_options, block);
+ } else {
+ return name;
+ };
+ } else {
+ return this.link_to(name, url, html_options);
+ };
+ };
+
+ EJS.Helpers.prototype.link_to_unless_current = function(name, url, html_options, block) {
+ html_options = html_options || {};
+ return this.link_to_unless(this.is_current_page(url), name, url, html_options, block);
+ };
+
+
+ EJS.Helpers.prototype.password_field_tag = function(name, value, html_options) {
+ return this.input_field_tag(name, value, 'password', html_options);
+ };
+
+ EJS.Helpers.prototype.select_tag = function(name, value, choices, html_options) {
+ html_options = html_options || {};
+ html_options.id = html_options.id || name;
+ html_options.value = value;
+ html_options.name = name;
+ var txt = '';
+ txt += this.start_tag_for('select', html_options);
+ for(var i = 0; i < choices.length; i++) {
+ var choice = choices[i];
+ var optionOptions = {value: choice.value};
+ if(choice.value == value) optionOptions.selected ='selected';
+ txt += this.start_tag_for('option', optionOptions )+choice.text+this.tag_end('option');
+ };
+ txt += this.tag_end('select');
+ return txt;
+ };
+
+ EJS.Helpers.prototype.single_tag_for = function(tag, html_options) {
+ return this.tag(tag, html_options, '/>');
+ };
+
+ EJS.Helpers.prototype.start_tag_for = function(tag, html_options) {
+ return this.tag(tag, html_options);
+ };
+
+ EJS.Helpers.prototype.submit_tag = function(name, html_options) {
+ html_options = html_options || {};
+ html_options.type = html_options.type || 'submit';
+ html_options.value = name || 'Submit';
+ return this.single_tag_for('input', html_options);
+ };
+
+ EJS.Helpers.prototype.tag = function(tag, html_options, end) {
+ if(!end) var end = '>';
+ var txt = ' ';
+ for(var attr in html_options) {
+ if(html_options[attr] != null) {
+ var value = html_options[attr].toString();
+ } else {
+ var value='';
+ };
+ // special case because "class" is a reserved word in IE
+ if(attr == "Class") attr = "class";
+ if( value.indexOf("'") != -1 ) {
+ txt += attr+'=\"'+value+'\" ';
+ } else {
+ txt += attr+"='"+value+"' ";
+ };
+ };
+ return '<' + tag + txt + end;
+ };
+
+ EJS.Helpers.prototype.tag_end = function(tag) {
+ return '</'+tag+'>';
+ };
+
+ EJS.Helpers.prototype.text_area_tag = function(name, value, html_options) {
+ html_options = html_options || {};
+ html_options.id = html_options.id || name;
+ html_options.name = html_options.name || name;
+ value = value || '';
+ if(html_options.size) {
+ html_options.cols = html_options.size.split('x')[0];
+ html_options.rows = html_options.size.split('x')[1];
+ delete html_options.size;
+ };
+ html_options.cols = html_options.cols || 50;
+ html_options.rows = html_options.rows || 4;
+ return this.start_tag_for('textarea', html_options)+value+this.tag_end('textarea');
+ };
+
+ EJS.Helpers.prototype.text_tag = EJS.Helpers.prototype.text_area_tag;
+
+ EJS.Helpers.prototype.text_field_tag = function(name, value, html_options) {
+ return this.input_field_tag(name, value, 'text', html_options);
+ };
+
+ EJS.Helpers.prototype.url_for = function(url) {
+ return 'window.location="' + url + '";';
+ };
+
+ EJS.Helpers.prototype.img_tag = function(image_location, alt, options){
+ options = options || {};
+ options.src = image_location;
+ options.alt = alt;
+ return this.single_tag_for('img', options);
+ };
+
+ // -------------------------------------------------------------
+
+ Sammy = Sammy || {};
+
+ Sammy.EJS = function(app, method_alias) {
+
+ // *Helper:* Uses simple templating to parse ERB like templates.
+ //
+ // ### Arguments
+ //
+ // * `template` A String template. '<% %>' tags are evaluated as Javascript and replaced with the elements in data.
+ // * `data` An Object containing the replacement values for the template.
+ //data is extended with the <tt>EventContext</tt> allowing you to call its methods within the template.
+ // * `name` An optional String name to cache the template.
+ //
+ var template = function(template, data, name) {
+ // use name for caching
+ if (typeof name == 'undefined') name = template;
+ return new EJS({text: template, name: name}).render(data);
+ };
+
+ // set the default method name/extension
+ if (!method_alias) method_alias = 'ejs';
+
+ // create the helper at the method alias
+ app.helper(method_alias, template);
+
+ };
+
+})(jQuery);
http://git-wip-us.apache.org/repos/asf/cordova-registry-web/blob/f50cc931/attachments/sammy/plugins/sammy.form.js
----------------------------------------------------------------------
diff --git a/attachments/sammy/plugins/sammy.form.js b/attachments/sammy/plugins/sammy.form.js
new file mode 100644
index 0000000..78edb87
--- /dev/null
+++ b/attachments/sammy/plugins/sammy.form.js
@@ -0,0 +1,274 @@
+(function($) {
+
+ Sammy = Sammy || {};
+
+ function getStringContent(object, content) {
+ if (typeof content === 'undefined') {
+ return '';
+ } else if ($.isFunction(content)) {
+ content = content.apply(object);
+ }
+ return content.toString();
+ };
+
+ function simple_element(tag, attributes, content) {
+ var html = "<";
+ html += tag;
+ if (typeof attributes != 'undefined') {
+ $.each(attributes, function(key, value) {
+ if (value != null) {
+ html += " " + key + "='";
+ html += getStringContent(attributes, value).replace(/\'/g, "\'");
+ html += "'";
+ }
+ });
+ }
+ if (content === false) {
+ html += ">";
+ } else if (typeof content != 'undefined') {
+ html += ">";
+ html += getStringContent(this, content);
+ html += "</" + tag + ">";
+ } else {
+ html += " />";
+ }
+ return html;
+ };
+
+ // Sammy.FormBuilder is based very closely on the Rails FormBuilder classes.
+ // Its goal is to make it easy to create HTML forms for creating and editing
+ // JavaScript objects. It eases the process by auto-populating existing values
+ // into form inputs and creating input names suitable for parsing by
+ // Sammy.NestedParams and other backend frameworks.
+ //
+ // You initialize a Sammy.FormBuilder by passing the 'name' of the object and
+ // the object itself. Once initialized you create form elements with the object's
+ // prototype methods. Each of these methods returns a string of HTML suitable for
+ // appending through a template or directly with jQuery.
+ //
+ // ### Example
+ //
+ // var item = {
+ // name: 'My Item',
+ // price: '$25.50',
+ // meta: {
+ // id: '123'
+ // }
+ // };
+ // var form = new Sammy.FormBuilder('item', item);
+ // form.text('name');
+ // //=> <input type='text' name='item[form]' value='My Item' />
+ //
+ // Nested attributes can be accessed/referred to by a 'keypath' which is
+ // basically a string representation of the dot notation.
+ //
+ // form.hidden('meta.id');
+ // //=> <input type='hidden' name='item[meta][id]' value='123' />
+ //
+ Sammy.FormBuilder = function(name, object) {
+ this.name = name;
+ this.object = object;
+ };
+
+ $.extend(Sammy.FormBuilder.prototype, {
+
+ // creates the open form tag with the object attributes
+ open: function(attributes) {
+ return simple_element('form', $.extend({'method': 'post', 'action': '#/' + this.name + 's'}, attributes), false);
+ },
+
+ // closes the form
+ close: function() {
+ return '</form>';
+ },
+
+ // creates a label for `keypath` with the text `content
+ // with an optional `attributes` object
+ label: function(keypath, content, attributes) {
+ var attrs = {'for': this._attributesForKeyPath(keypath).name};
+ return simple_element('label', $.extend(attrs, attributes), content);
+ },
+
+ // creates a hidden input for `keypath` with an optional `attributes` object
+ hidden: function(keypath, attributes) {
+ attributes = $.extend({type: 'hidden'}, this._attributesForKeyPath(keypath), attributes);
+ return simple_element('input', attributes);
+ },
+
+ // creates a text input for `keypath` with an optional `attributes` object
+ text: function(keypath, attributes) {
+ attributes = $.extend({type: 'text'}, this._attributesForKeyPath(keypath), attributes);
+ return simple_element('input', attributes);
+ },
+
+ // creates a textarea for `keypath` with an optional `attributes` object
+ textarea: function(keypath, attributes) {
+ var current;
+ attributes = $.extend(this._attributesForKeyPath(keypath), attributes);
+ current = attributes.value;
+ delete attributes['value'];
+ return simple_element('textarea', attributes, current);
+ },
+
+ // creates a password input for `keypath` with an optional `attributes` object
+ password: function(keypath, attributes) {
+ return this.text(keypath, $.extend({type: 'password'}, attributes));
+ },
+
+ // creates a select element for `keypath` with the option elements
+ // specified by an array in `options`. If `options` is an array of arrays,
+ // the first element in each subarray becomes the text of the option and the
+ // second becomes the value.
+ //
+ // ### Example
+ //
+ // var options = [
+ // ['Small', 's'],
+ // ['Medium', 'm'],
+ // ['Large', 'l']
+ // ];
+ // form.select('size', options);
+ // //=> <select name='item[size]'><option value='s'>Small</option> ...
+ //
+ //
+ select: function(keypath, options, attributes) {
+ var option_html = "", selected;
+ attributes = $.extend(this._attributesForKeyPath(keypath), attributes);
+ selected = attributes.value;
+ delete attributes['value'];
+ $.each(options, function(i, option) {
+ var value, text, option_attrs;
+ if ($.isArray(option)) {
+ value = option[1], text = option[0];
+ } else {
+ value = option, text = option;
+ }
+ option_attrs = {value: getStringContent(this.object, value)};
+ // select the correct option
+ if (value === selected) { option_attrs.selected = 'selected'; }
+ option_html += simple_element('option', option_attrs, text);
+ });
+ return simple_element('select', attributes, option_html);
+ },
+
+ // creates a radio input for keypath with the value `value`. Multiple
+ // radios can be created with different value, if `value` equals the
+ // current value of the key of the form builder's object the attribute
+ // checked='checked' will be added.
+ radio: function(keypath, value, attributes) {
+ var selected;
+ attributes = $.extend(this._attributesForKeyPath(keypath), attributes);
+ selected = attributes.value;
+ attributes.value = getStringContent(this.object, value);
+ if (selected == attributes.value) {
+ attributes.checked = 'checked';
+ }
+ return simple_element('input', $.extend({type:'radio'}, attributes));
+ },
+
+ // creates a checkbox input for keypath with the value `value`. Multiple
+ // checkboxes can be created with different value, if `value` equals the
+ // current value of the key of the form builder's object the attribute
+ // checked='checked' will be added.
+ //
+ // By default `checkbox()` also generates a hidden element whose value is
+ // the inverse of the value given. This is known hack to get around a common
+ // gotcha where browsers and jQuery itself does not include 'unchecked'
+ // elements in the list of submittable inputs. This ensures that a value
+ // should always be passed to Sammy and hence the server. You can disable
+ // the creation of the hidden element by setting the `hidden_element` attribute
+ // to `false`
+ checkbox: function(keypath, value, attributes) {
+ var content = "";
+ if (!attributes) { attributes = {}; }
+ if (attributes.hidden_element !== false) {
+ content += this.hidden(keypath, {'value': !value});
+ }
+ delete attributes['hidden_element'];
+ content += this.radio(keypath, value, $.extend({type: 'checkbox'}, attributes));
+ return content;
+ },
+
+ // creates a submit input for `keypath` with an optional `attributes` object
+ submit: function(attributes) {
+ return simple_element('input', $.extend({'type': 'submit'}, attributes));
+ },
+
+ _attributesForKeyPath: function(keypath) {
+ var builder = this,
+ keys = $.isArray(keypath) ? keypath : keypath.split(/\./),
+ name = builder.name,
+ value = builder.object,
+ class_name = builder.name;
+
+ $.each(keys, function(i, key) {
+ if ((typeof value === 'undefined') || value == '') {
+ value = ''
+ } else if (typeof key == 'number' || key.match(/^\d+$/)) {
+ value = value[parseInt(key, 10)];
+ } else {
+ value = value[key];
+ }
+ name += "[" + key + "]";
+ class_name += "-" + key;
+ });
+ return {'name': name,
+ 'value': getStringContent(builder.object, value),
+ 'class': class_name};
+ }
+ });
+
+ // Sammy.Form is a Sammy plugin that adds form building helpers to a
+ // Sammy.Application
+ Sammy.Form = function(app) {
+
+ app.helpers({
+ // simple_element is a simple helper for creating HTML tags.
+ //
+ // ### Arguments
+ //
+ // * `tag` the HTML tag to generate e.g. input, p, etc/
+ // * `attributes` an object representing the attributes of the element as
+ // key value pairs. e.g. {class: 'element-class'}
+ // * `content` an optional string representing the content for the
+ // the element. If ommited, the element becomes self closing
+ //
+ simple_element: simple_element,
+
+ // formFor creates a Sammy.Form builder object with the passed `name`
+ // and `object` and passes it as an argument to the `content_callback`.
+ // This is a shortcut for creating FormBuilder objects for use within
+ // templates.
+ //
+ // ### Example
+ //
+ // // in item_form.template
+ //
+ // <% formFor('item', item, function(f) { %>
+ // <%= f.open({action: '#/items'}) %>
+ // <p>
+ // <%= f.label('name') %>
+ // <%= f.text('name') %>
+ // </p>
+ // <p>
+ // <%= f.submit() %>
+ // </p>
+ // <%= f.close() %>
+ // <% }); %>
+ //
+ formFor: function(name, object, content_callback) {
+ var builder;
+ // define a form with just a name
+ if ($.isFunction(object)) {
+ content_callback = object;
+ object = this[name];
+ }
+ builder = new Sammy.FormBuilder(name, object),
+ content_callback.apply(this, [builder]);
+ return builder;
+ }
+ });
+
+ };
+
+})(jQuery);
http://git-wip-us.apache.org/repos/asf/cordova-registry-web/blob/f50cc931/attachments/sammy/plugins/sammy.haml.js
----------------------------------------------------------------------
diff --git a/attachments/sammy/plugins/sammy.haml.js b/attachments/sammy/plugins/sammy.haml.js
new file mode 100644
index 0000000..9ea579d
--- /dev/null
+++ b/attachments/sammy/plugins/sammy.haml.js
@@ -0,0 +1,553 @@
+(function($) {
+
+ /*
+ port of http://github.com/creationix/haml-js
+ version v0.2.2 - 2010-04-05
+ by Tim Caswell <ti...@creationix.com>
+ */
+
+ var matchers, self_close_tags, embedder;
+
+ function html_escape(text) {
+ return (text + "").
+ replace(/&/g, "&").
+ replace(/</g, "<").
+ replace(/>/g, ">").
+ replace(/\"/g, """);
+ }
+
+ function render_attribs(attribs) {
+ var key, value, result = [];
+ for (key in attribs) {
+ if (key !== 'content' && attribs.hasOwnProperty(key)) {
+ switch (attribs[key]) {
+ case 'undefined':
+ case 'false':
+ case 'null':
+ case '""':
+ break;
+ default:
+ try {
+ value = JSON.parse("[" + attribs[key] +"]")[0];
+ if (value === true) {
+ value = key;
+ } else if (typeof value === 'string' && embedder.test(value)) {
+ value = '" +\n' + parse_interpol(html_escape(value)) + ' +\n"';
+ } else {
+ value = html_escape(value);
+ }
+ result.push(" " + key + '=\\"' + value + '\\"');
+ } catch (e) {
+ result.push(" " + key + '=\\"" + html_escape(' + attribs[key] + ') + "\\"');
+ }
+ }
+ }
+ }
+ return result.join("");
+ }
+
+ // Parse the attribute block using a state machine
+ function parse_attribs(line) {
+ var attributes = {},
+ l = line.length,
+ i, c,
+ count = 1,
+ quote = false,
+ skip = false,
+ open, close, joiner, seperator,
+ pair = {
+ start: 1,
+ middle: null,
+ end: null
+ };
+
+ if (!(l > 0 && (line.charAt(0) === '{' || line.charAt(0) === '('))) {
+ return {
+ content: line[0] === ' ' ? line.substr(1, l) : line
+ };
+ }
+ open = line.charAt(0);
+ close = (open === '{') ? '}' : ')';
+ joiner = (open === '{') ? ':' : '=';
+ seperator = (open === '{') ? ',' : ' ';
+
+ function process_pair() {
+ if (typeof pair.start === 'number' &&
+ typeof pair.middle === 'number' &&
+ typeof pair.end === 'number') {
+ var key = line.substr(pair.start, pair.middle - pair.start).trim(),
+ value = line.substr(pair.middle + 1, pair.end - pair.middle - 1).trim();
+ attributes[key] = value;
+ }
+ pair = {
+ start: null,
+ middle: null,
+ end: null
+ };
+ }
+
+ for (i = 1; count > 0; i += 1) {
+
+ // If we reach the end of the line, then there is a problem
+ if (i > l) {
+ throw "Malformed attribute block";
+ }
+
+ c = line.charAt(i);
+ if (skip) {
+ skip = false;
+ } else {
+ if (quote) {
+ if (c === '\\') {
+ skip = true;
+ }
+ if (c === quote) {
+ quote = false;
+ }
+ } else {
+ if (c === '"' || c === "'") {
+ quote = c;
+ }
+
+ if (count === 1) {
+ if (c === joiner) {
+ pair.middle = i;
+ }
+ if (c === seperator || c === close) {
+ pair.end = i;
+ process_pair();
+ if (c === seperator) {
+ pair.start = i + 1;
+ }
+ }
+ }
+
+ if (c === open) {
+ count += 1;
+ }
+ if (c === close) {
+ count -= 1;
+ }
+ }
+ }
+ }
+ attributes.content = line.substr(i, line.length);
+ return attributes;
+ }
+
+ // Split interpolated strings into an array of literals and code fragments.
+ function parse_interpol(value) {
+ var items = [],
+ pos = 0,
+ next = 0,
+ match;
+ while (true) {
+ // Match up to embedded string
+ next = value.substr(pos).search(embedder);
+ if (next < 0) {
+ if (pos < value.length) {
+ items.push(JSON.stringify(value.substr(pos)));
+ }
+ break;
+ }
+ items.push(JSON.stringify(value.substr(pos, next)));
+ pos += next;
+
+ // Match embedded string
+ match = value.substr(pos).match(embedder);
+ next = match[0].length;
+ if (next < 0) { break; }
+ items.push(match[1] || match[2]);
+ pos += next;
+ }
+ return items.filter(function (part) { return part && part.length > 0}).join(" +\n");
+ }
+
+ // Used to find embedded code in interpolated strings.
+ embedder = /\#\{([^}]*)\}/;
+
+ self_close_tags = ["meta", "img", "link", "br", "hr", "input", "area", "base"];
+
+ // All matchers' regexps should capture leading whitespace in first capture
+ // and trailing content in last capture
+ matchers = [
+ // html tags
+ {
+ regexp: /^(\s*)((?:[.#%][a-z_\-][a-z0-9_\-]*)+)(.*)$/i,
+ process: function () {
+ var tag, classes, ids, attribs, content;
+ tag = this.matches[2];
+ classes = tag.match(/\.([a-z_\-][a-z0-9_\-]*)/gi);
+ ids = tag.match(/\#([a-z_\-][a-z0-9_\-]*)/gi);
+ tag = tag.match(/\%([a-z_\-][a-z0-9_\-]*)/gi);
+
+ // Default to <div> tag
+ tag = tag ? tag[0].substr(1, tag[0].length) : 'div';
+
+ attribs = this.matches[3];
+ if (attribs) {
+ attribs = parse_attribs(attribs);
+ if (attribs.content) {
+ this.contents.unshift(attribs.content.trim());
+ delete(attribs.content);
+ }
+ } else {
+ attribs = {};
+ }
+
+ if (classes) {
+ classes = classes.map(function (klass) {
+ return klass.substr(1, klass.length);
+ }).join(' ');
+ if (attribs['class']) {
+ try {
+ attribs['class'] = JSON.stringify(classes + " " + JSON.parse(attribs['class']));
+ } catch (e) {
+ attribs['class'] = JSON.stringify(classes + " ") + " + " + attribs['class'];
+ }
+ } else {
+ attribs['class'] = JSON.stringify(classes);
+ }
+ }
+ if (ids) {
+ ids = ids.map(function (id) {
+ return id.substr(1, id.length);
+ }).join(' ');
+ if (attribs.id) {
+ attribs.id = JSON.stringify(ids + " ") + attribs.id;
+ } else {
+ attribs.id = JSON.stringify(ids);
+ }
+ }
+
+ attribs = render_attribs(attribs);
+
+ content = this.render_contents();
+ if (content === '""') {
+ content = '';
+ }
+
+ if (self_close_tags.indexOf(tag) == -1) {
+ return '"<' + tag + attribs + '>"' +
+ (content.length > 0 ? ' + \n' + content : "") +
+ ' + \n"</' + tag + '>"';
+ } else {
+ return '"<' + tag + attribs + ' />"';
+ }
+ }
+ },
+
+ // each loops
+ {
+ regexp: /^(\s*)(?::for|:each)\s+(?:([a-z_][a-z_\-]*),\s*)?([a-z_][a-z_\-]*)\s+in\s+(.*)(\s*)$/i,
+ process: function () {
+ var ivar = this.matches[2] || '__key__', // index
+ vvar = this.matches[3], // value
+ avar = this.matches[4], // array
+ rvar = '__result__'; // results
+
+ if (this.matches[5]) {
+ this.contents.unshift(this.matches[5]);
+ }
+ return '(function () { ' +
+ 'var ' + rvar + ' = [], ' + ivar + ', ' + vvar + '; ' +
+ 'for (' + ivar + ' in ' + avar + ') { ' +
+ 'if (' + avar + '.hasOwnProperty(' + ivar + ')) { ' +
+ vvar + ' = ' + avar + '[' + ivar + ']; ' +
+ rvar + '.push(\n' + (this.render_contents() || "''") + '\n); ' +
+ '} } return ' + rvar + '.join(""); }).call(this)';
+ }
+ },
+
+ // if statements
+ {
+ regexp: /^(\s*):if\s+(.*)\s*$/i,
+ process: function () {
+ var condition = this.matches[2];
+ return '(function () { ' +
+ 'if (' + condition + ') { ' +
+ 'return (\n' + (this.render_contents() || '') + '\n);' +
+ '} else { return ""; } }).call(this)';
+ }
+ },
+
+ // declarations
+ {
+ regexp: /^()!!!(?:\s*(.*))\s*$/,
+ process: function () {
+ var line = '';
+ switch ((this.matches[2] || '').toLowerCase()) {
+ case '':
+ // XHTML 1.0 Transitional
+ line = '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">';
+ break;
+ case 'strict':
+ case '1.0':
+ // XHTML 1.0 Strict
+ line = '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">';
+ break;
+ case 'frameset':
+ // XHTML 1.0 Frameset
+ line = '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">';
+ break;
+ case '5':
+ // XHTML 5
+ line = '<!DOCTYPE html>';
+ break;
+ case '1.1':
+ // XHTML 1.1
+ line = '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">';
+ break;
+ case 'basic':
+ // XHTML Basic 1.1
+ line = '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML Basic 1.1//EN" "http://www.w3.org/TR/xhtml-basic/xhtml-basic11.dtd">';
+ break;
+ case 'mobile':
+ // XHTML Mobile 1.2
+ line = '<!DOCTYPE html PUBLIC "-//WAPFORUM//DTD XHTML Mobile 1.2//EN" "http://www.openmobilealliance.org/tech/DTD/xhtml-mobile12.dtd">';
+ break;
+ case 'xml':
+ // XML
+ line = "<?xml version='1.0' encoding='utf-8' ?>";
+ break;
+ case 'xml iso-8859-1':
+ // XML iso-8859-1
+ line = "<?xml version='1.0' encoding='iso-8859-1' ?>";
+ break;
+ }
+ return JSON.stringify(line + "\n");
+ }
+ },
+
+ // Embedded markdown. Needs to be added to exports externally.
+ {
+ regexp: /^(\s*):markdown\s*$/i,
+ process: function () {
+ return parse_interpol(exports.Markdown.encode(this.contents.join("\n")));
+ }
+ },
+
+ // script blocks
+ {
+ regexp: /^(\s*):(?:java)?script\s*$/,
+ process: function () {
+ return parse_interpol('\n<script type="text/javascript">\n' +
+ '//<![CDATA[\n' +
+ this.contents.join("\n") +
+ "\n//]]>\n</script>\n");
+ }
+ },
+
+ // css blocks
+ {
+ regexp: /^(\s*):css\s*$/,
+ process: function () {
+ return JSON.stringify('\n<style type="text/css">\n' +
+ this.contents.join("\n") +
+ "\n</style>\n");
+ }
+ },
+
+ ];
+
+ function compile(lines) {
+ var block = false,
+ output = [];
+
+ // If lines is a string, turn it into an array
+ if (typeof lines === 'string') {
+ lines = lines.trim().split("\n");
+ }
+
+ lines.forEach(function(line) {
+ var match, found = false;
+
+ // Collect all text as raw until outdent
+ if (block) {
+ match = block.check_indent(line);
+ if (match) {
+ block.contents.push(match[1] || "");
+ return;
+ } else {
+ output.push(block.process());
+ block = false;
+ }
+ }
+
+ matchers.forEach(function (matcher) {
+ if (!found) {
+ match = matcher.regexp(line);
+ if (match) {
+ block = {
+ contents: [],
+ matches: match,
+ check_indent: new RegExp("^(?:\\s*|" + match[1] + " (.*))$"),
+ process: matcher.process,
+ render_contents: function () {
+ return compile(this. contents);
+ }
+ };
+ found = true;
+ }
+ }
+ });
+
+ // Match plain text
+ if (!found) {
+ output.push(function () {
+ // Escaped plain text
+ if (line[0] === '\\') {
+ return parse_interpol(line.substr(1, line.length));
+ }
+
+ // Plain variable data
+ if (line[0] === '=') {
+ line = line.substr(1, line.length).trim();
+ try {
+ return parse_interpol(JSON.parse(line));
+ } catch (e) {
+ return line;
+ }
+ }
+
+ // HTML escape variable data
+ if (line.substr(0, 2) === "&=") {
+ line = line.substr(2, line.length).trim();
+ try {
+ return JSON.stringify(html_escape(JSON.parse(line)));
+ } catch (e2) {
+ return 'html_escape(' + line + ')';
+ }
+ }
+
+ // Plain text
+ return parse_interpol(line);
+ }());
+ }
+
+ });
+ if (block) {
+ output.push(block.process());
+ }
+ return output.filter(function (part) { return part && part.length > 0}).join(" +\n");
+ };
+
+ function optimize(js) {
+ var new_js = [], buffer = [], part, end;
+
+ function flush() {
+ if (buffer.length > 0) {
+ new_js.push(JSON.stringify(buffer.join("")) + end);
+ buffer = [];
+ }
+ }
+ js.split("\n").forEach(function (line) {
+ part = line.match(/^(\".*\")(\s*\+\s*)?$/);
+ if (!part) {
+ flush();
+ new_js.push(line);
+ return;
+ }
+ end = part[2] || "";
+ part = part[1];
+ try {
+ buffer.push(JSON.parse(part));
+ } catch (e) {
+ flush();
+ new_js.push(line);
+ }
+ });
+ flush();
+ return new_js.join("\n");
+ };
+
+ function Haml(haml) {
+ var js = optimize(compile(haml));
+ return new Function("locals",
+ html_escape + "\n" +
+ "with(locals || {}) {\n" +
+ " try {\n" +
+ " return (" + js + ");\n" +
+ " } catch (e) {\n" +
+ " return \"\\n<pre class='error'>\" + html_escape(e.stack) + \"</pre>\\n\";\n" +
+ " }\n" +
+ "}");
+ }
+
+
+ Sammy = Sammy || {};
+
+ // <tt>Sammy.Haml</tt> provides a quick way of using haml style templates in your app.
+ // The plugin itself includes the haml-js library created by Tim Caswell at
+ // at http://github.com/creationix/haml-js
+ //
+ // Haml is an alternative HTML syntax that is really great for describing
+ // the structure of HTML documents.
+ //
+ // By default using Sammy.Haml in your app adds the <tt>haml()</tt> method to the EventContext
+ // prototype. However, just like <tt>Sammy.Template</tt> you can change the default name of the method
+ // by passing a second argument (e.g. you could use the hml() as the method alias so that all the template
+ // files could be in the form file.hml instead of file.haml)
+ //
+ // ### Example
+ //
+ // The template (mytemplate.haml):
+ //
+ // %h1&= title
+ //
+ // Hey, #{name}! Welcome to Haml!
+ //
+ // The app:
+ //
+ // var $.app = $.sammy(function() {
+ // // include the plugin
+ // this.use(Sammy.Haml);
+ //
+ // this.get('#/hello/:name', function() {
+ // // set local vars
+ // this.title = 'Hello!'
+ // this.name = this.params.name;
+ // // render the template and pass it through haml
+ // this.partial('mytemplate.haml');
+ // });
+ //
+ // });
+ //
+ // If I go to #/hello/AQ in the browser, Sammy will render this to the <tt>body</tt>:
+ //
+ // <h1>Hello!</h1>
+ //
+ // Hey, AQ! Welcome to HAML!
+ //
+ // Note: You dont have to include the haml.js file on top of the plugin as the plugin
+ // includes the full source.
+ //
+ Sammy.Haml = function(app, method_alias) {
+ app.use(Sammy.JSON);
+
+ var haml_cache = {};
+ // *Helper* Uses haml-js to parse a template and interpolate and work with the passed data
+ //
+ // ### Arguments
+ //
+ // * `template` A String template.
+ // * `data` An Object containing the replacement values for the template.
+ // data is extended with the <tt>EventContext</tt> allowing you to call its methods within the template.
+ //
+ var haml = function(template, data, name) {
+ // use name for caching
+ if (typeof name == 'undefined') name = template;
+ var fn = haml_cache[name];
+ if (!fn) {
+ fn = haml_cache[name] = Haml(template);
+ }
+ return fn($.extend({}, this, data));
+ };
+
+ // set the default method name/extension
+ if (!method_alias) method_alias = 'haml';
+ app.helper(method_alias, haml);
+
+ };
+
+})(jQuery);
http://git-wip-us.apache.org/repos/asf/cordova-registry-web/blob/f50cc931/attachments/sammy/plugins/sammy.json.js
----------------------------------------------------------------------
diff --git a/attachments/sammy/plugins/sammy.json.js b/attachments/sammy/plugins/sammy.json.js
new file mode 100644
index 0000000..83b9dd0
--- /dev/null
+++ b/attachments/sammy/plugins/sammy.json.js
@@ -0,0 +1,362 @@
+(function($) {
+
+ // json2.js - only included if native json does not exist
+ // http://www.json.org/js.html
+ if (!window.JSON) {
+ window.JSON = {};
+ }
+ (function () {
+
+ function f(n) {
+ // Format integers to have at least two digits.
+ return n < 10 ? '0' + n : n;
+ }
+
+ if (typeof Date.prototype.toJSON !== 'function') {
+
+ Date.prototype.toJSON = function (key) {
+
+ return this.getUTCFullYear() + '-' +
+ f(this.getUTCMonth() + 1) + '-' +
+ f(this.getUTCDate()) + 'T' +
+ f(this.getUTCHours()) + ':' +
+ f(this.getUTCMinutes()) + ':' +
+ f(this.getUTCSeconds()) + 'Z';
+ };
+
+ String.prototype.toJSON =
+ Number.prototype.toJSON =
+ Boolean.prototype.toJSON = function (key) {
+ return this.valueOf();
+ };
+ }
+
+ var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
+ escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
+ gap,
+ indent,
+ meta = { // table of character substitutions
+ '\b': '\\b',
+ '\t': '\\t',
+ '\n': '\\n',
+ '\f': '\\f',
+ '\r': '\\r',
+ '"' : '\\"',
+ '\\': '\\\\'
+ },
+ rep;
+
+
+ function quote(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 escape
+ // sequences.
+
+ escapable.lastIndex = 0;
+ return escapable.test(string) ?
+ '"' + string.replace(escapable, function (a) {
+ var c = meta[a];
+ return typeof c === 'string' ? c :
+ '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
+ }) + '"' :
+ '"' + string + '"';
+ }
+
+
+ function str(key, holder) {
+
+ // Produce a string from holder[key].
+
+ var i, // The loop counter.
+ k, // The member key.
+ v, // The member value.
+ length,
+ mind = gap,
+ partial,
+ value = holder[key];
+
+ // If the value has a toJSON method, call it to obtain a replacement value.
+
+ if (value && typeof value === 'object' &&
+ typeof value.toJSON === 'function') {
+ value = value.toJSON(key);
+ }
+
+ // If we were called with a replacer function, then call the replacer to
+ // obtain a replacement value.
+
+ if (typeof rep === 'function') {
+ value = rep.call(holder, key, value);
+ }
+
+ // What happens next depends on the value's type.
+
+ switch (typeof value) {
+ case 'string':
+ return quote(value);
+
+ case 'number':
+
+ // JSON numbers must be finite. Encode non-finite numbers as null.
+
+ return isFinite(value) ? String(value) : 'null';
+
+ case 'boolean':
+ case 'null':
+
+ // If the value is a boolean or null, convert it to a string. Note:
+ // typeof null does not produce 'null'. The case is included here in
+ // the remote chance that this gets fixed someday.
+
+ return String(value);
+
+ // If the type is 'object', we might be dealing with an object or an array or
+ // null.
+
+ case 'object':
+
+ // Due to a specification blunder in ECMAScript, typeof null is 'object',
+ // so watch out for that case.
+
+ if (!value) {
+ return 'null';
+ }
+
+ // Make an array to hold the partial results of stringifying this object value.
+
+ gap += indent;
+ partial = [];
+
+ // Is the value an array?
+
+ if (Object.prototype.toString.apply(value) === '[object Array]') {
+
+ // The value is an array. Stringify every element. Use null as a placeholder
+ // for non-JSON values.
+
+ length = value.length;
+ for (i = 0; i < length; i += 1) {
+ partial[i] = str(i, value) || 'null';
+ }
+
+ // Join all of the elements together, separated with commas, and wrap them in
+ // brackets.
+
+ v = partial.length === 0 ? '[]' :
+ gap ? '[\n' + gap +
+ partial.join(',\n' + gap) + '\n' +
+ mind + ']' :
+ '[' + partial.join(',') + ']';
+ gap = mind;
+ return v;
+ }
+
+ // If the replacer is an array, use it to select the members to be stringified.
+
+ if (rep && typeof rep === 'object') {
+ length = rep.length;
+ for (i = 0; i < length; i += 1) {
+ k = rep[i];
+ if (typeof k === 'string') {
+ v = str(k, value);
+ if (v) {
+ partial.push(quote(k) + (gap ? ': ' : ':') + v);
+ }
+ }
+ }
+ } else {
+
+ // Otherwise, iterate through all of the keys in the object.
+
+ for (k in value) {
+ if (Object.hasOwnProperty.call(value, k)) {
+ v = str(k, value);
+ if (v) {
+ partial.push(quote(k) + (gap ? ': ' : ':') + v);
+ }
+ }
+ }
+ }
+
+ // Join all of the member texts together, separated with commas,
+ // and wrap them in braces.
+
+ v = partial.length === 0 ? '{}' :
+ gap ? '{\n' + gap + partial.join(',\n' + gap) + '\n' +
+ mind + '}' : '{' + partial.join(',') + '}';
+ gap = mind;
+ return v;
+ }
+ }
+
+ // If the JSON object does not yet have a stringify method, give it one.
+
+ if (typeof JSON.stringify !== 'function') {
+ JSON.stringify = function (value, replacer, space) {
+
+ // The stringify method takes a value and an optional replacer, and an optional
+ // space parameter, and returns a JSON text. The replacer can be a function
+ // that can replace values, or an array of strings that will select the keys.
+ // A default replacer method can be provided. Use of the space parameter can
+ // produce text that is more easily readable.
+
+ var i;
+ gap = '';
+ indent = '';
+
+ // If the space parameter is a number, make an indent string containing that
+ // many spaces.
+
+ if (typeof space === 'number') {
+ for (i = 0; i < space; i += 1) {
+ indent += ' ';
+ }
+
+ // If the space parameter is a string, it will be used as the indent string.
+
+ } else if (typeof space === 'string') {
+ indent = space;
+ }
+
+ // If there is a replacer, it must be a function or an array.
+ // Otherwise, throw an error.
+
+ rep = replacer;
+ if (replacer && typeof replacer !== 'function' &&
+ (typeof replacer !== 'object' ||
+ typeof replacer.length !== 'number')) {
+ throw new Error('JSON.stringify');
+ }
+
+ // Make a fake root object containing our value under the key of ''.
+ // Return the result of stringifying the value.
+
+ return str('', {'': value});
+ };
+ }
+
+
+ // If the JSON object does not yet have a parse method, give it one.
+
+ if (typeof JSON.parse !== 'function') {
+ JSON.parse = function (text, reviver) {
+
+ // The parse method takes a text and an optional reviver function, and returns
+ // a JavaScript value if the text is a valid JSON text.
+
+ var j;
+
+ function walk(holder, key) {
+
+ // The walk method is used to recursively walk the resulting structure so
+ // that modifications can be made.
+
+ var k, v, value = holder[key];
+ if (value && typeof value === 'object') {
+ for (k in value) {
+ if (Object.hasOwnProperty.call(value, k)) {
+ v = walk(value, k);
+ if (v !== undefined) {
+ value[k] = v;
+ } else {
+ delete value[k];
+ }
+ }
+ }
+ }
+ return reviver.call(holder, key, value);
+ }
+
+
+ // Parsing happens in four stages. In the first stage, we replace certain
+ // Unicode characters with escape sequences. JavaScript handles many characters
+ // incorrectly, either silently deleting them, or treating them as line endings.
+
+ cx.lastIndex = 0;
+ if (cx.test(text)) {
+ text = text.replace(cx, function (a) {
+ return '\\u' +
+ ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
+ });
+ }
+
+ // In the second stage, we run the text against regular expressions that look
+ // for non-JSON patterns. 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 second stage into 4 regexp operations in order to work around
+ // crippling inefficiencies in IE's and Safari's regexp engines. First we
+ // replace the JSON 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(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@').
+ replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']').
+ replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) {
+
+ // In the third 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 fourth stage, we recursively walk the new structure, passing
+ // each name/value pair to a reviver function for possible transformation.
+
+ return typeof reviver === 'function' ?
+ walk({'': j}, '') : j;
+ }
+
+ // If the text is not JSON parseable, then a SyntaxError is thrown.
+
+ throw new SyntaxError('JSON.parse');
+ };
+ }
+ }());
+
+ Sammy = Sammy || {};
+
+ // Sammy.JSON is a simple wrapper around Douglas Crockford's ever-useful json2.js
+ // (http://www.json.org/js.html]) Sammy.JSON includes the top level JSON object if
+ // it doesn't already exist (a.k.a. does not override the native implementation that
+ // some browsers include). It also adds a <tt>json()</tt> helper to a Sammy app when
+ // included.
+ Sammy.JSON = function(app) {
+
+ app.helpers({
+ // json is a polymorphic function that translates objects aback and forth
+ // from JSON to JS. If given a string, it will parse into JS, if given a JS
+ // object it will stringify into JSON.
+ //
+ // ### Example
+ //
+ // var app = $.sammy(function() {
+ // this.use(Sammy.JSON);
+ //
+ // this.get('#/', function() {
+ // this.json({user_id: 123}); //=> "{\"user_id\":\"123\"}"
+ // this.json("{\"user_id\":\"123\"}"); //=> [object Object]
+ // this.json("{\"user_id\":\"123\"}").user_id; //=> "123"
+ // });
+ // })
+ //
+ //
+ json: function(object) {
+ if (typeof object == 'string') {
+ return JSON.parse(object);
+ } else {
+ return JSON.stringify(object);
+ }
+ }
+ });
+
+ }
+
+})(jQuery);
http://git-wip-us.apache.org/repos/asf/cordova-registry-web/blob/f50cc931/attachments/sammy/plugins/sammy.meld.js
----------------------------------------------------------------------
diff --git a/attachments/sammy/plugins/sammy.meld.js b/attachments/sammy/plugins/sammy.meld.js
new file mode 100644
index 0000000..9753969
--- /dev/null
+++ b/attachments/sammy/plugins/sammy.meld.js
@@ -0,0 +1,140 @@
+(function($) {
+
+ Sammy = Sammy || {};
+
+ // `Sammy.Meld` is a simple templating engine that uses the power of jQuery's
+ // DOM manipulation to easily meld JSON data and HTML templates very quickly.
+ //
+ // The template can either be a string (i.e. loaded from a remote template)
+ // or a DOM Element/jQuery object. This allows you to have templates be DOM
+ // elements as the initial document load.
+ //
+ // ### Example
+ //
+ // The simplest case is a nested `<div>` whose class name is tied to a
+ // property of a JS object.
+ //
+ // Template:
+ //
+ // <div class="post">
+ // <div class="title"></div>
+ // <div class="entry"></div>
+ // <div class="author">
+ // <span class="name"></span>
+ // </div>
+ // </div>
+ //
+ // Data:
+ //
+ // {
+ // "post": {
+ // "title": "My Post",
+ // "entry": "My Entry",
+ // "author": {
+ // "name": "@aq"
+ // }
+ // }
+ // }
+ //
+ // Result:
+ //
+ // <div class="post">
+ // <div class="title">My Post</div>
+ // <div class="entry">My Entry</div>
+ // <div class="author">
+ // <span class="name">@aq</span>
+ // </div>
+ // </div>
+ //
+ // Templates can be much more complex, and more deeply nested.
+ // More examples can be found in `test/fixtures/meld/`
+ //
+ // If you don't think the lookup by classes is semantic for you, you can easily
+ // switch the method of lookup by defining a selector function in the options
+ //
+ // For example:
+ //
+ // meld($('.post'), post_data, {
+ // selector: function(k) {
+ // return '[data-key=' + k + ']';
+ // }
+ // });
+ //
+ // Would look for template nodes like `<div data-key='entry'>`
+ //
+ Sammy.Meld = function(app, method_alias) {
+ var default_options = {
+ selector: function(k) { return '.' + k; },
+ remove_false: true
+ };
+
+ var meld = function(template, data, options) {
+ var $template = $(template);
+
+ options = $.extend(default_options, options || {});
+
+ if (typeof data === 'string') {
+ $template.html(data);
+ } else {
+ $.each(data, function(key, value) {
+ var selector = options.selector(key),
+ $sub = $template.filter(selector),
+ $container,
+ $item,
+ is_list = false,
+ subindex = $template.index($sub);
+
+ if ($sub.length === 0) { $sub = $template.find(selector); }
+ if ($sub.length > 0) {
+ if ($.isArray(value)) {
+ $container = $('<div/>');
+ if ($sub.is('ol, ul')) {
+ is_list = true;
+ $item = $sub.children('li:first');
+ if ($item.length == 0) { $item = $('<li/>'); }
+ } else if ($sub.children().length == 1) {
+ is_list = true;
+ $item = $sub.children(':first').clone();
+ } else {
+ $item = $sub.clone();
+ }
+ for (var i = 0; i < value.length; i++) {
+ $container.append(meld($item.clone(), value[i], options));
+ }
+ if (is_list) {
+ $sub.html($container.html());
+ } else if ($sub[0] == $template[0]) {
+ $template = $($container.html());
+ } else if (subindex >= 0) {
+ var args = [subindex, 1];
+ args = args.concat($container.children().get());
+ $template.splice.apply($template, args);
+ }
+ } else if (options.remove_false && value === false) {
+ $template.splice(subindex, 1);
+ } else if (typeof value === 'object') {
+ if ($sub.is(':empty')) {
+ $sub.attr(value, true);
+ } else {
+ $sub.html(meld($sub.html(), value, options));
+ }
+ } else {
+ $sub.html(value.toString());
+ }
+ } else {
+ $template.attr({key: value}, true);
+ }
+ });
+ }
+ var dom = $template;
+ return dom;
+ };
+
+ // set the default method name/extension
+ if (!method_alias) method_alias = 'meld';
+ // create the helper at the method alias
+ app.helper(method_alias, meld);
+
+ };
+
+})(jQuery);