mirror of
https://github.com/galaxyproject/galaxy.git
synced 2026-09-24 16:30:27 +08:00
Merge.
This commit is contained in:
@@ -3,6 +3,7 @@ Classes for generating HTML forms
|
||||
"""
|
||||
|
||||
import logging,sys
|
||||
from cgi import escape
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
class BaseField(object):
|
||||
@@ -28,7 +29,7 @@ class TextField(BaseField):
|
||||
self.value = value or ""
|
||||
def get_html( self, prefix="" ):
|
||||
return '<input type="text" name="%s%s" size="%d" value="%s">' \
|
||||
% ( prefix, self.name, self.size, self.value )
|
||||
% ( prefix, self.name, self.size, escape(str(self.value), quote=True) )
|
||||
def set_size(self, size):
|
||||
self.size = int( size )
|
||||
|
||||
@@ -49,7 +50,7 @@ class TextArea(BaseField):
|
||||
self.value = value or ""
|
||||
def get_html( self, prefix="" ):
|
||||
return '<textarea name="%s%s" rows="%d" cols="%d">%s</textarea>' \
|
||||
% ( prefix, self.name, self.rows, self.cols, self.value )
|
||||
% ( prefix, self.name, self.rows, self.cols, escape(str(self.value), quote=True) )
|
||||
def set_size(self, rows, cols):
|
||||
self.rows = rows
|
||||
self.cols = cols
|
||||
@@ -113,7 +114,7 @@ class HiddenField(BaseField):
|
||||
self.name = name
|
||||
self.value = value or ""
|
||||
def get_html( self, prefix="" ):
|
||||
return '<input type="hidden" name="%s%s" value="%s">' % ( prefix, self.name, self.value )
|
||||
return '<input type="hidden" name="%s%s" value="%s">' % ( prefix, self.name, escape(str(self.value), quote=True) )
|
||||
|
||||
class SelectField(BaseField):
|
||||
"""
|
||||
@@ -190,9 +191,9 @@ class SelectField(BaseField):
|
||||
if len(self.options) > 2 and ctr % 2 == 1:
|
||||
style = " class=\"odd_row\""
|
||||
if selected:
|
||||
rval.append( '<div%s><input type="checkbox" name="%s%s" value="%s" checked>%s</div>' % ( style, prefix, self.name, value, text) )
|
||||
rval.append( '<div%s><input type="checkbox" name="%s%s" value="%s" checked>%s</div>' % ( style, prefix, self.name, escape(str(value), quote=True), text) )
|
||||
else:
|
||||
rval.append( '<div%s><input type="checkbox" name="%s%s" value="%s">%s</div>' % ( style, prefix, self.name, value, text) )
|
||||
rval.append( '<div%s><input type="checkbox" name="%s%s" value="%s">%s</div>' % ( style, prefix, self.name, escape(str(value), quote=True), text) )
|
||||
ctr += 1
|
||||
return "\n".join( rval )
|
||||
def get_html_radio( self, prefix="" ):
|
||||
@@ -204,7 +205,7 @@ class SelectField(BaseField):
|
||||
style = " class=\"odd_row\""
|
||||
if selected: selected_text = " checked"
|
||||
else: selected_text = ""
|
||||
rval.append( '<div%s><input type="radio" name="%s%s"%s value="%s"%s>%s</div>' % ( style, prefix, self.name, self.refresh_on_change_text, value, selected_text, text ) )
|
||||
rval.append( '<div%s><input type="radio" name="%s%s"%s value="%s"%s>%s</div>' % ( style, prefix, self.name, self.refresh_on_change_text, escape(str(value), quote=True), selected_text, text ) )
|
||||
ctr += 1
|
||||
return "\n".join( rval )
|
||||
def get_html_default( self, prefix="" ):
|
||||
@@ -217,9 +218,9 @@ class SelectField(BaseField):
|
||||
selected_text = " selected"
|
||||
last_selected_value = value
|
||||
else: selected_text = ""
|
||||
rval.append( '<option value="%s"%s>%s</option>' % ( value, selected_text, text ) )
|
||||
rval.append( '<option value="%s"%s>%s</option>' % ( escape(str(value), quote=True), selected_text, text ) )
|
||||
if last_selected_value:
|
||||
last_selected_value = ' last_selected_value="%s"' % last_selected_value
|
||||
last_selected_value = ' last_selected_value="%s"' % escape(str(last_selected_value), quote=True)
|
||||
rval.insert( 0, '<select name="%s%s"%s%s%s>' % ( prefix, self.name, multiple, self.refresh_on_change_text, last_selected_value ) )
|
||||
rval.append( '</select>' )
|
||||
return "\n".join( rval )
|
||||
@@ -326,12 +327,12 @@ class DrillDownField( BaseField ):
|
||||
if option['value'] in expanded_options:
|
||||
default_state = 'expanded'
|
||||
default_icon = '[-]'
|
||||
html.append( '<li><span class="toolParameterExpandableCollapsable">%s</span><input type="%s" name="%s%s" value="%s"%s">%s' % ( default_icon, self.display, prefix, self.name, option['value'], selected, option['name']) )
|
||||
html.append( '<li><span class="toolParameterExpandableCollapsable">%s</span><input type="%s" name="%s%s" value="%s"%s">%s' % ( default_icon, self.display, prefix, self.name, escape(str(option['value']), quote=True), selected, option['name']) )
|
||||
html.append( '<ul class="toolParameterExpandableCollapsable" default_state="%s">' % default_state )
|
||||
recurse_options( html, option['options'], expanded_options )
|
||||
html.append( '</ul>')
|
||||
else:
|
||||
html.append( '<li><input type="%s" name="%s%s" value="%s"%s">%s' % ( self.display, prefix, self.name, option['value'], selected, option['name']) )
|
||||
html.append( '<li><input type="%s" name="%s%s" value="%s"%s">%s' % ( self.display, prefix, self.name, escape(str(option['value']), quote=True), selected, option['name']) )
|
||||
html.append( '</li>' )
|
||||
rval = []
|
||||
rval.append( '<div><ul class="toolParameterExpandableCollapsable">' )
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
|
||||
<head>
|
||||
<title>Flash External Object</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
<script type="text/javascript">
|
||||
/**
|
||||
* This function captures the flash_ready event. We need to relay this
|
||||
* back to the parent so it knows flash is ready.
|
||||
*/
|
||||
function flash_ready(){
|
||||
parent.flash_ready();
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="http://fpdownload.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=8,0,0,0" width="1" height="1" id="jStoreFlash"><param name="allowScriptAccess" value="always" /><param name="movie" value="jStore.swf" /><param name="quality" value="high" /><param name="bgcolor" value="#ffcc00" /><embed src="jStore.swf" quality="high" bgcolor="#ffcc00" width="1" height="1" name="jStoreFlash" align="middle" allowScriptAccess="always" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" /></object>
|
||||
</body>
|
||||
</html>
|
||||
Binary file not shown.
@@ -359,6 +359,7 @@ function Workflow( canvas_container ) {
|
||||
this.nodes = {};
|
||||
this.name = null;
|
||||
this.has_changes = false;
|
||||
this.active_form_has_changes = false;
|
||||
}
|
||||
$.extend( Workflow.prototype, {
|
||||
add_node : function( node ) {
|
||||
@@ -438,6 +439,28 @@ $.extend( Workflow.prototype, {
|
||||
});
|
||||
});
|
||||
},
|
||||
enable_auto_save : function() {
|
||||
// Implements auto-saving based on whether the inputs change. We consider
|
||||
// "changed" to be when a field is accessed and not necessarily modified
|
||||
// because of an issue where "onchange" is not triggered when activating
|
||||
// another node, or saving the workflow.
|
||||
outer_this = this;
|
||||
$(".toolFormBody").find("input,textarea,select").each( function() {
|
||||
$(this).focus( function() {
|
||||
outer_this.active_form_has_changes = true;
|
||||
});
|
||||
});
|
||||
},
|
||||
check_changes_in_active_form : function() {
|
||||
// If active form has changed, save it
|
||||
if (this.active_form_has_changes) {
|
||||
this.has_changes = true;
|
||||
$(".toolFormBody").find("form").each( function() {
|
||||
$(this).submit();
|
||||
});
|
||||
this.active_form_has_changes = false;
|
||||
}
|
||||
},
|
||||
clear_active_node : function() {
|
||||
if ( this.active_node ) {
|
||||
this.active_node.make_inactive();
|
||||
@@ -447,6 +470,7 @@ $.extend( Workflow.prototype, {
|
||||
},
|
||||
activate_node : function( node ) {
|
||||
if ( this.active_node != node ) {
|
||||
this.check_changes_in_active_form();
|
||||
this.clear_active_node();
|
||||
parent.show_form_for_tool( node.form_html, node );
|
||||
node.make_active();
|
||||
@@ -461,6 +485,7 @@ $.extend( Workflow.prototype, {
|
||||
}
|
||||
},
|
||||
layout : function () {
|
||||
this.check_changes_in_active_form();
|
||||
// Prepare predecessor / successor tracking
|
||||
var n_pred = {};
|
||||
var successors = {};
|
||||
@@ -502,7 +527,7 @@ $.extend( Workflow.prototype, {
|
||||
var v = level_parents[k];
|
||||
delete n_pred[v];
|
||||
for ( var sk in successors[v] ) {
|
||||
n_pred[ sucessors[v][sk] ] -= 1;
|
||||
n_pred[ successors[v][sk] ] -= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -805,6 +830,10 @@ $.extend( CanvasManager.prototype, {
|
||||
self.draw_overview();
|
||||
});
|
||||
|
||||
/* Disable dragging for child element of the panel so that resizing can
|
||||
only be done by dragging the borders */
|
||||
$("#overview-border div").bind("drag", function(e) { });
|
||||
|
||||
},
|
||||
update_viewport_overlay: function() {
|
||||
var cc = this.cc,
|
||||
|
||||
@@ -0,0 +1,748 @@
|
||||
/*!
|
||||
* jStore - Persistent Client-Side Storage
|
||||
*
|
||||
* Copyright (c) 2009 Eric Garside (http://eric.garside.name)
|
||||
*
|
||||
* Dual licensed under:
|
||||
* MIT: http://www.opensource.org/licenses/mit-license.php
|
||||
* GPLv3: http://www.opensource.org/licenses/gpl-3.0.html
|
||||
*//**
|
||||
* Javascript Class Framework
|
||||
*
|
||||
* Copyright (c) 2008 John Resig (http://ejohn.org/blog/simple-javascript-inheritance/)
|
||||
* Inspired by base2 and Prototype
|
||||
*/
|
||||
(function(){
|
||||
var initializing = false, fnTest = /xyz/.test(function(){xyz;}) ? /\b_super\b/ : /.*/;
|
||||
|
||||
// The base Class implementation (does nothing)
|
||||
this.Class = function(){};
|
||||
|
||||
// Create a new Class that inherits from this class
|
||||
Class.extend = function(prop) {
|
||||
var _super = this.prototype;
|
||||
|
||||
// Instantiate a base class (but only create the instance,
|
||||
// don't run the init constructor)
|
||||
initializing = true;
|
||||
var prototype = new this();
|
||||
initializing = false;
|
||||
|
||||
// Copy the properties over onto the new prototype
|
||||
for (var name in prop) {
|
||||
// Check if we're overwriting an existing function
|
||||
prototype[name] = typeof prop[name] == "function" &&
|
||||
typeof _super[name] == "function" && fnTest.test(prop[name]) ?
|
||||
(function(name, fn){
|
||||
return function() {
|
||||
var tmp = this._super;
|
||||
|
||||
// Add a new ._super() method that is the same method
|
||||
// but on the super-class
|
||||
this._super = _super[name];
|
||||
|
||||
// The method only need to be bound temporarily, so we
|
||||
// remove it when we're done executing
|
||||
var ret = fn.apply(this, arguments);
|
||||
this._super = tmp;
|
||||
|
||||
return ret;
|
||||
};
|
||||
})(name, prop[name]) :
|
||||
prop[name];
|
||||
}
|
||||
|
||||
// The dummy class constructor
|
||||
function Class() {
|
||||
// All construction is actually done in the init method
|
||||
if ( !initializing && this.init )
|
||||
this.init.apply(this, arguments);
|
||||
}
|
||||
|
||||
// Populate our constructed prototype object
|
||||
Class.prototype = prototype;
|
||||
|
||||
// Enforce the constructor to be what we expect
|
||||
Class.constructor = Class;
|
||||
|
||||
// And make this class extendable
|
||||
Class.extend = arguments.callee;
|
||||
|
||||
return Class;
|
||||
};
|
||||
})();
|
||||
/*!
|
||||
* jStore Delegate Framework
|
||||
* Copyright (c) 2009 Eric Garside (http://eric.garside.name)
|
||||
*/
|
||||
(function($){
|
||||
|
||||
this.jStoreDelegate = Class.extend({
|
||||
init: function(parent){
|
||||
// The Object this delgate operates for
|
||||
this.parent = parent;
|
||||
// Container for callbacks to dispatch.
|
||||
// eventType => [ callback, callback, ... ]
|
||||
this.callbacks = {};
|
||||
},
|
||||
bind: function(event, callback){
|
||||
if ( !$.isFunction(callback) ) return this;
|
||||
if ( !this.callbacks[ event ] ) this.callbacks[ event ] = [];
|
||||
|
||||
this.callbacks[ event ].push(callback);
|
||||
|
||||
return this;
|
||||
},
|
||||
trigger: function(){
|
||||
var parent = this.parent,
|
||||
args = [].slice.call(arguments),
|
||||
event = args.shift(),
|
||||
handlers = this.callbacks[ event ];
|
||||
|
||||
if ( !handlers ) return false;
|
||||
|
||||
$.each(handlers, function(){ this.apply(parent, args) });
|
||||
return this;
|
||||
}
|
||||
});
|
||||
|
||||
})(jQuery);/**
|
||||
* jStore-jQuery Interface
|
||||
* Copyright (c) 2009 Eric Garside (http://eric.garside.name)
|
||||
*/
|
||||
(function($){
|
||||
|
||||
// Setup the jStore namespace in jQuery for options storage
|
||||
$.jStore = {};
|
||||
|
||||
// Seed the options in
|
||||
$.extend($.jStore, {
|
||||
EngineOrder: [],
|
||||
// Engines should put their availability tests within jStore.Availability
|
||||
Availability: {},
|
||||
// Defined engines should enter themselves into the jStore.Engines
|
||||
Engines: {},
|
||||
// Instanciated engines should exist within jStore.Instances
|
||||
Instances: {},
|
||||
// The current engine to use for storage
|
||||
CurrentEngine: null,
|
||||
// Provide global settings for overwriting
|
||||
defaults: {
|
||||
project: null,
|
||||
engine: null,
|
||||
autoload: true,
|
||||
flash: 'jStore.Flash.html'
|
||||
},
|
||||
// Boolean for ready state handling
|
||||
isReady: false,
|
||||
// Boolean for flash ready state handling
|
||||
isFlashReady: false,
|
||||
// An event delegate
|
||||
delegate: new jStoreDelegate($.jStore)
|
||||
.bind('jStore-ready', function(engine){
|
||||
$.jStore.isReady = true;
|
||||
if ($.jStore.defaults.autoload) engine.connect();
|
||||
})
|
||||
.bind('flash-ready', function(){
|
||||
$.jStore.isFlashReady = true;
|
||||
})
|
||||
});
|
||||
|
||||
// Enable ready callback for jStore
|
||||
$.jStore.ready = function(callback){
|
||||
if ($.jStore.isReady) callback.apply($.jStore, [$.jStore.CurrentEngine]);
|
||||
else $.jStore.delegate.bind('jStore-ready', callback);
|
||||
}
|
||||
|
||||
// Enable failure callback registration for jStore
|
||||
$.jStore.fail = function(callback){
|
||||
$.jStore.delegate.bind('jStore-failure', callback);
|
||||
}
|
||||
|
||||
// Enable ready callback for Flash
|
||||
$.jStore.flashReady = function(callback){
|
||||
if ($.jStore.isFlashReady) callback.apply($.jStore, [$.jStore.CurrentEngine]);
|
||||
else $.jStore.delegate.bind('flash-ready', callback);
|
||||
}
|
||||
|
||||
// Enable and test an engine
|
||||
$.jStore.use = function(engine, project, identifier){
|
||||
project = project || $.jStore.defaults.project || location.hostname.replace(/\./g, '-') || 'unknown';
|
||||
|
||||
var e = $.jStore.Engines[engine.toLowerCase()] || null,
|
||||
name = (identifier ? identifier + '.' : '') + project + '.' + engine;
|
||||
|
||||
if ( !e ) throw 'JSTORE_ENGINE_UNDEFINED';
|
||||
|
||||
// Instanciate the engine
|
||||
e = new e(project, name);
|
||||
|
||||
// Prevent against naming conflicts
|
||||
if ($.jStore.Instances[name]) throw 'JSTORE_JRI_CONFLICT';
|
||||
|
||||
// Test the engine
|
||||
if (e.isAvailable()){
|
||||
$.jStore.Instances[name] = e; // The Easy Way
|
||||
if (!$.jStore.CurrentEngine){
|
||||
$.jStore.CurrentEngine = e;
|
||||
}
|
||||
$.jStore.delegate.trigger('jStore-ready', e);
|
||||
} else {
|
||||
if (!e.autoload) // Not available
|
||||
throw 'JSTORE_ENGINE_UNAVILABLE';
|
||||
else { // The hard way
|
||||
e.included(function(){
|
||||
if (this.isAvailable()) { // Worked out
|
||||
$.jStore.Instances[name] = this;
|
||||
// If there is no current engine, use this one
|
||||
if (!$.jStore.CurrentEngine){
|
||||
$.jStore.CurrentEngine = this;
|
||||
}
|
||||
$.jStore.delegate.trigger('jStore-ready', this);
|
||||
}
|
||||
else $.jStore.delegate.trigger('jStore-failure', this);
|
||||
}).include();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Set the current storage engine
|
||||
$.jStore.setCurrentEngine = function(name){
|
||||
if (!$.jStore.Instances.length ) // If no instances exist, attempt to load one
|
||||
return $.jStore.FindEngine();
|
||||
|
||||
if (!name && $.jStore.Instances.length >= 1) { // If no name is specified, use the first engine
|
||||
$.jStore.delegate.trigger('jStore-ready', $.jStore.Instances[0]);
|
||||
return $.jStore.CurrentEngine = $.jStore.Instances[0];
|
||||
}
|
||||
|
||||
if (name && $.jStore.Instances[name]) { // If a name is specified and exists, use it
|
||||
$.jStore.delegate.trigger('jStore-ready', $.jStore.Instances[name]);
|
||||
return $.jStore.CurrentEngine = $.jStore.Instances[name];
|
||||
}
|
||||
|
||||
throw 'JSTORE_JRI_NO_MATCH';
|
||||
}
|
||||
|
||||
// Test all possible engines for straightforward useability
|
||||
$.jStore.FindEngine = function(){
|
||||
$.each($.jStore.EngineOrder, function(k){
|
||||
if ($.jStore.Availability[this]()){ // Find the first, easiest option and use it.
|
||||
$.jStore.use(this, $.jStore.defaults.project, 'default');
|
||||
return false;
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// Provide a simple interface for storing/getting values
|
||||
$.jStore.store = function(key, value){
|
||||
if (!$.jStore.CurrentEngine) return false;
|
||||
|
||||
if ( !value ) // Executing a get command
|
||||
return $.jStore.CurrentEngine.get(key);
|
||||
// Executing a set command
|
||||
return $.jStore.CurrentEngine.set(key, value);
|
||||
}
|
||||
// Provide a simple interface for storing/getting values
|
||||
$.jStore.remove = function(key){
|
||||
if (!$.jStore.CurrentEngine) return false;
|
||||
|
||||
return $.jStore.CurrentEngine.rem(key);
|
||||
}
|
||||
|
||||
// Provide a chainable interface for storing values/getting a value at the end of a chain
|
||||
$.fn.store = function(key, value){
|
||||
if (!$.jStore.CurrentEngine) return this;
|
||||
|
||||
var result = $.jStore.store(key, value);
|
||||
|
||||
return !value ? result : this;
|
||||
}
|
||||
|
||||
// Provide a chainable interface for removing values
|
||||
$.fn.removeStore = function(key){
|
||||
$.jStore.remove(key);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
// Provide a way for users to call for auto-loading
|
||||
$.jStore.load = function(){
|
||||
if ($.jStore.defaults.engine)
|
||||
return $.jStore.use($.jStore.defaults.engine, $.jStore.defaults.project, 'default');
|
||||
|
||||
// Attempt to find a valid engine, and catch any exceptions if we can't
|
||||
try {
|
||||
$.jStore.FindEngine();
|
||||
} catch (e) {}
|
||||
}
|
||||
|
||||
})(jQuery);
|
||||
/**
|
||||
* jStore Engine Core
|
||||
* Copyright (c) 2009 Eric Garside (http://eric.garside.name)
|
||||
*/
|
||||
(function($){
|
||||
|
||||
this.StorageEngine = Class.extend({
|
||||
init: function(project, name){
|
||||
// Configure the project name
|
||||
this.project = project;
|
||||
// The JRI name given by the manager
|
||||
this.jri = name;
|
||||
// Cache the data so we can work synchronously
|
||||
this.data = {};
|
||||
// The maximum limit of the storage engine
|
||||
this.limit = -1;
|
||||
// Third party script includes
|
||||
this.includes = [];
|
||||
// Create an event delegate for users to subscribe to event triggers
|
||||
this.delegate = new jStoreDelegate(this)
|
||||
.bind('engine-ready', function(){
|
||||
this.isReady = true;
|
||||
})
|
||||
.bind('engine-included', function(){
|
||||
this.hasIncluded = true;
|
||||
});
|
||||
// If enabled, the manager will check availability, then run include(), then check again
|
||||
this.autoload = false; // This should be changed by the engines, if they have required includes
|
||||
// When set, we're ready to transact data
|
||||
this.isReady = false;
|
||||
// When the includer is finished, it will set this to true
|
||||
this.hasIncluded = false;
|
||||
},
|
||||
// Performs all necessary script includes
|
||||
include: function(){
|
||||
var self = this,
|
||||
total = this.includes.length,
|
||||
count = 0;
|
||||
|
||||
$.each(this.includes, function(){
|
||||
$.ajax({type: 'get', url: this, dataType: 'script', cache: true,
|
||||
success: function(){
|
||||
count++;
|
||||
if (count == total) self.delegate.trigger('engine-included');
|
||||
}
|
||||
})
|
||||
});
|
||||
},
|
||||
// This should be overloaded with an actual functionality presence check
|
||||
isAvailable: function(){
|
||||
return false;
|
||||
},
|
||||
/** Event Subscription Shortcuts **/
|
||||
ready: function(callback){
|
||||
if (this.isReady) callback.apply(this);
|
||||
else this.delegate.bind('engine-ready', callback);
|
||||
return this;
|
||||
},
|
||||
included: function(callback){
|
||||
if (this.hasIncluded) callback.apply(this);
|
||||
else this.delegate.bind('engine-included', callback);
|
||||
return this;
|
||||
},
|
||||
/** Cache Data Access **/
|
||||
get: function(key){
|
||||
return this.data[key] || null;
|
||||
},
|
||||
set: function(key, value){
|
||||
this.data[key] = value;
|
||||
return value;
|
||||
},
|
||||
rem: function(key){
|
||||
var beforeDelete = this.data[key];
|
||||
this.data[key] = null;
|
||||
return beforeDelete;
|
||||
}
|
||||
});
|
||||
|
||||
})(jQuery);
|
||||
/*!
|
||||
* jStore DOM Storage Engine
|
||||
* Copyright (c) 2009 Eric Garside (http://eric.garside.name)
|
||||
*/
|
||||
(function($){
|
||||
|
||||
// Set up a static test function for this instance
|
||||
var sessionAvailability = $.jStore.Availability.session = function(){
|
||||
return !!window.sessionStorage;
|
||||
},
|
||||
localAvailability = $.jStore.Availability.local = function(){
|
||||
return !!(window.localStorage || window.globalStorage);
|
||||
};
|
||||
|
||||
this.jStoreDom = StorageEngine.extend({
|
||||
init: function(project, name){
|
||||
// Call the parental init object
|
||||
this._super(project, name);
|
||||
|
||||
// The type of storage engine
|
||||
this.type = 'DOM';
|
||||
|
||||
// Set the Database limit
|
||||
this.limit = 5 * 1024 * 1024;
|
||||
},
|
||||
connect: function(){
|
||||
// Fire our delegate to indicate we're ready for data transactions
|
||||
this.delegate.trigger('engine-ready');
|
||||
},
|
||||
get: function(key){
|
||||
var out = this.db.getItem(key);
|
||||
// Gecko's getItem returns {value: 'the value'}, WebKit returns 'the value'
|
||||
return out && out.value ? out.value : out
|
||||
},
|
||||
set: function(key, value){
|
||||
this.db.setItem(key,value);
|
||||
return value;
|
||||
},
|
||||
rem: function(key){
|
||||
var out = this.get(key);
|
||||
this.db.removeItem(key);
|
||||
return out
|
||||
}
|
||||
})
|
||||
|
||||
this.jStoreLocal = jStoreDom.extend({
|
||||
connect: function(){
|
||||
// Gecko uses a non-standard globalStorage[ www.example.com ] DOM access object for persistant storage.
|
||||
this.db = !window.globalStorage ? window.localStorage : window.globalStorage[location.hostname];
|
||||
this._super();
|
||||
},
|
||||
isAvailable: localAvailability
|
||||
})
|
||||
|
||||
this.jStoreSession = jStoreDom.extend({
|
||||
connect: function(){
|
||||
this.db = sessionStorage;
|
||||
this._super();
|
||||
},
|
||||
isAvailable: sessionAvailability
|
||||
})
|
||||
|
||||
$.jStore.Engines.local = jStoreLocal;
|
||||
$.jStore.Engines.session = jStoreSession;
|
||||
|
||||
// Store the ordering preference
|
||||
$.jStore.EngineOrder[ 1 ] = 'local';
|
||||
|
||||
})(jQuery);
|
||||
/*!
|
||||
* jStore Flash Storage Engine
|
||||
* Copyright (c) 2009 Eric Garside (http://eric.garside.name)
|
||||
* jStore.swf Copyright (c) 2008 Daniel Bulli (http://www.nuff-respec.com)
|
||||
*/
|
||||
(function($){
|
||||
|
||||
// Set up a static test function for this instance
|
||||
var avilability = $.jStore.Availability.flash = function(){
|
||||
return !!($.jStore.hasFlash('8.0.0'));
|
||||
}
|
||||
|
||||
this.jStoreFlash = StorageEngine.extend({
|
||||
init: function(project, name){
|
||||
// Call the parental init object
|
||||
this._super(project, name);
|
||||
|
||||
// The type of storage engine
|
||||
this.type = 'Flash';
|
||||
|
||||
// Bind our flashReady function to the jStore Delegate
|
||||
var self = this;
|
||||
$.jStore.flashReady(function(){ self.flashReady() });
|
||||
},
|
||||
connect: function(){
|
||||
var name = 'jstore-flash-embed-' + this.project;
|
||||
|
||||
// To make Flash Storage work on IE, we have to load up an iFrame
|
||||
// which contains an HTML page that embeds the object using an
|
||||
// object tag wrapping an embed tag. Of course, this is unnecessary for
|
||||
// all browsers except for IE, which, to my knowledge, is the only browser
|
||||
// in existance where you need to complicate your code to fix bugs. Goddamnit. :(
|
||||
$(document.body)
|
||||
.append('<iframe style="height:1px;width:1px;position:absolute;left:0;top:0;margin-left:-100px;" ' +
|
||||
'id="jStoreFlashFrame" src="' +$.jStore.defaults.flash + '"></iframe>');
|
||||
},
|
||||
flashReady: function(e){
|
||||
var iFrame = $('#jStoreFlashFrame')[0];
|
||||
|
||||
// IE
|
||||
if (iFrame.Document && $.isFunction(iFrame.Document['jStoreFlash'].f_get_cookie)) this.db = iFrame.Document['jStoreFlash'];
|
||||
// Safari && Firefox
|
||||
else if (iFrame.contentWindow && iFrame.contentWindow.document){
|
||||
var doc = iFrame.contentWindow.document;
|
||||
// Safari
|
||||
if ($.isFunction($('object', $(doc))[0].f_get_cookie)) this.db = $('object', $(doc))[0];
|
||||
// Firefox
|
||||
else if ($.isFunction($('embed', $(doc))[0].f_get_cookie)) this.db = $('embed', $(doc))[0];
|
||||
}
|
||||
|
||||
// We're ready to process data
|
||||
if (this.db) this.delegate.trigger('engine-ready');
|
||||
},
|
||||
isAvailable: avilability,
|
||||
get: function(key){
|
||||
var out = this.db.f_get_cookie(key);
|
||||
return out == 'null' ? null : out;
|
||||
},
|
||||
set: function(key, value){
|
||||
this.db.f_set_cookie(key, value);
|
||||
return value;
|
||||
},
|
||||
rem: function(key){
|
||||
var beforeDelete = this.get(key);
|
||||
this.db.f_delete_cookie(key);
|
||||
return beforeDelete;
|
||||
}
|
||||
})
|
||||
|
||||
$.jStore.Engines.flash = jStoreFlash;
|
||||
|
||||
// Store the ordering preference
|
||||
$.jStore.EngineOrder[ 2 ] = 'flash';
|
||||
|
||||
/**
|
||||
* Flash Detection functions copied from the jQuery Flash Plugin
|
||||
* Copyright (c) 2006 Luke Lutman (http://jquery.lukelutman.com/plugins/flash)
|
||||
* Dual licensed under the MIT and GPL licenses.
|
||||
* http://www.opensource.org/licenses/mit-license.php
|
||||
* http://www.opensource.org/licenses/gpl-license.php
|
||||
*/
|
||||
$.jStore.hasFlash = function(version){
|
||||
var pv = $.jStore.flashVersion().match(/\d+/g),
|
||||
rv = version.match(/\d+/g);
|
||||
|
||||
for(var i = 0; i < 3; i++) {
|
||||
pv[i] = parseInt(pv[i] || 0);
|
||||
rv[i] = parseInt(rv[i] || 0);
|
||||
// player is less than required
|
||||
if(pv[i] < rv[i]) return false;
|
||||
// player is greater than required
|
||||
if(pv[i] > rv[i]) return true;
|
||||
}
|
||||
// major version, minor version and revision match exactly
|
||||
return true;
|
||||
}
|
||||
|
||||
$.jStore.flashVersion = function(){
|
||||
// ie
|
||||
try {
|
||||
try {
|
||||
// avoid fp6 minor version lookup issues
|
||||
// see: http://blog.deconcept.com/2006/01/11/getvariable-setvariable-crash-internet-explorer-flash-6/
|
||||
var axo = new ActiveXObject('ShockwaveFlash.ShockwaveFlash.6');
|
||||
try { axo.AllowScriptAccess = 'always'; }
|
||||
catch(e) { return '6,0,0'; }
|
||||
} catch(e) {}
|
||||
return new ActiveXObject('ShockwaveFlash.ShockwaveFlash').GetVariable('$version').replace(/\D+/g, ',').match(/^,?(.+),?$/)[1];
|
||||
// other browsers
|
||||
} catch(e) {
|
||||
try {
|
||||
if(navigator.mimeTypes["application/x-shockwave-flash"].enabledPlugin){
|
||||
return (navigator.plugins["Shockwave Flash 2.0"] || navigator.plugins["Shockwave Flash"]).description.replace(/\D+/g, ",").match(/^,?(.+),?$/)[1];
|
||||
}
|
||||
} catch(e) {}
|
||||
}
|
||||
return '0,0,0';
|
||||
}
|
||||
|
||||
})(jQuery);
|
||||
|
||||
// Callback fired when ExternalInterface is established
|
||||
function flash_ready(){
|
||||
$.jStore.delegate.trigger('flash-ready');
|
||||
}
|
||||
/*!
|
||||
* jStore Google Gears Storage Engine
|
||||
* Copyright (c) 2009 Eric Garside (http://eric.garside.name)
|
||||
*/
|
||||
(function($){
|
||||
|
||||
// Set up a static test function for this instance
|
||||
var avilability = $.jStore.Availability.gears = function(){
|
||||
return !!(window.google && window.google.gears)
|
||||
}
|
||||
|
||||
this.jStoreGears = StorageEngine.extend({
|
||||
init: function(project, name){
|
||||
// Call the parental init object
|
||||
this._super(project, name);
|
||||
|
||||
// The type of storage engine
|
||||
this.type = 'Google Gears';
|
||||
|
||||
// Add required third-party scripts
|
||||
this.includes.push('http://code.google.com/apis/gears/gears_init.js');
|
||||
|
||||
// Allow Autoloading on fail
|
||||
this.autoload = true;
|
||||
},
|
||||
connect: function(){
|
||||
// Create our database connection
|
||||
var db = this.db = google.gears.factory.create('beta.database');
|
||||
db.open( 'jstore-' + this.project );
|
||||
db.execute( 'CREATE TABLE IF NOT EXISTS jstore (k TEXT UNIQUE NOT NULL PRIMARY KEY, v TEXT NOT NULL)' );
|
||||
|
||||
// Cache the data from the table
|
||||
this.updateCache();
|
||||
},
|
||||
updateCache: function(){
|
||||
// Read the database into our cache object
|
||||
var result = this.db.execute( 'SELECT k,v FROM jstore' );
|
||||
while (result.isValidRow()){
|
||||
this.data[result.field(0)] = result.field(1);
|
||||
result.next();
|
||||
} result.close();
|
||||
|
||||
// Fire our delegate to indicate we're ready for data transactions
|
||||
this.delegate.trigger('engine-ready');
|
||||
},
|
||||
isAvailable: avilability,
|
||||
set: function(key, value){
|
||||
// Update the database
|
||||
var db = this.db;
|
||||
db.execute( 'BEGIN' );
|
||||
db.execute( 'INSERT OR REPLACE INTO jstore(k, v) VALUES (?, ?)', [key,value] );
|
||||
db.execute( 'COMMIT' );
|
||||
return this._super(key, value);
|
||||
},
|
||||
rem: function(key){
|
||||
// Update the database
|
||||
var db = this.db;
|
||||
db.execute( 'BEGIN' );
|
||||
db.execute( 'DELETE FROM jstore WHERE k = ?', [key] );
|
||||
db.execute( 'COMMIT' );
|
||||
return this._super(key);
|
||||
}
|
||||
})
|
||||
|
||||
$.jStore.Engines.gears = jStoreGears;
|
||||
|
||||
// Store the ordering preference
|
||||
$.jStore.EngineOrder[ 3 ] = 'gears';
|
||||
|
||||
})(jQuery);
|
||||
/*!
|
||||
* jStore HTML5 Specification Storage Engine
|
||||
* Copyright (c) 2009 Eric Garside (http://eric.garside.name)
|
||||
*/
|
||||
(function($){
|
||||
|
||||
// Set up a static test function for this instance
|
||||
var avilability = $.jStore.Availability.html5 = function(){
|
||||
return !!window.openDatabase
|
||||
}
|
||||
|
||||
this.jStoreHtml5 = StorageEngine.extend({
|
||||
init: function(project, name){
|
||||
// Call the parental init object
|
||||
this._super(project, name);
|
||||
|
||||
// The type of storage engine
|
||||
this.type = 'HTML5';
|
||||
|
||||
// Set the Database limit
|
||||
this.limit = 1024 * 200;
|
||||
},
|
||||
connect: function(){
|
||||
// Create our database connection
|
||||
var db = this.db = openDatabase('jstore-' + this.project, '1.0', this.project, this.limit);
|
||||
if (!db) throw 'JSTORE_ENGINE_HTML5_NODB';
|
||||
db.transaction(function(db){
|
||||
db.executeSql( 'CREATE TABLE IF NOT EXISTS jstore (k TEXT UNIQUE NOT NULL PRIMARY KEY, v TEXT NOT NULL)' );
|
||||
});
|
||||
|
||||
// Cache the data from the table
|
||||
this.updateCache();
|
||||
},
|
||||
updateCache: function(){
|
||||
var self = this;
|
||||
// Read the database into our cache object
|
||||
this.db.transaction(function(db){
|
||||
db.executeSql( 'SELECT k,v FROM jstore', [], function(db, result){
|
||||
var rows = result.rows, i = 0, row;
|
||||
for (; i < rows.length; ++i){
|
||||
row = rows.item(i);
|
||||
self.data[row.k] = row.v;
|
||||
}
|
||||
|
||||
// Fire our delegate to indicate we're ready for data transactions
|
||||
self.delegate.trigger('engine-ready');
|
||||
});
|
||||
});
|
||||
},
|
||||
isAvailable: avilability,
|
||||
set: function(key, value){
|
||||
// Update the database
|
||||
this.db.transaction(function(db){
|
||||
db.executeSql( 'INSERT OR REPLACE INTO jstore(k, v) VALUES (?, ?)', [key,value]);
|
||||
});
|
||||
return this._super(key, value);
|
||||
},
|
||||
rem: function(key){
|
||||
// Update the database
|
||||
this.db.transaction(function(db){
|
||||
db.executeSql( 'DELETE FROM jstore WHERE k = ?', [key] )
|
||||
})
|
||||
return this._super(key);
|
||||
}
|
||||
})
|
||||
|
||||
$.jStore.Engines.html5 = jStoreHtml5;
|
||||
|
||||
// Store the ordering preference
|
||||
$.jStore.EngineOrder[ 0 ] = 'html5';
|
||||
|
||||
})(jQuery);
|
||||
/*!*
|
||||
* jStore IE Storage Engine
|
||||
* Copyright (c) 2009 Eric Garside (http://eric.garside.name)
|
||||
*/
|
||||
(function($){
|
||||
|
||||
// Set up a static test function for this instance
|
||||
var avilability = $.jStore.Availability.ie = function(){
|
||||
return !!window.ActiveXObject;
|
||||
}
|
||||
|
||||
this.jStoreIE = StorageEngine.extend({
|
||||
init: function(project, name){
|
||||
// Call the parental init object
|
||||
this._super(project, name);
|
||||
|
||||
// The type of storage engine
|
||||
this.type = 'IE';
|
||||
|
||||
// Allow Autoloading on fail
|
||||
this.limit = 64 * 1024;
|
||||
},
|
||||
connect: function(){
|
||||
// Create a hidden div to store attributes in
|
||||
this.db = $('<div style="display:none;behavior:url(\'#default#userData\')" id="jstore-' + this.project + '"></div>')
|
||||
.appendTo(document.body).get(0);
|
||||
// Fire our delegate to indicate we're ready for data transactions
|
||||
this.delegate.trigger('engine-ready');
|
||||
},
|
||||
isAvailable: avilability,
|
||||
get: function(key){
|
||||
this.db.load(this.project);
|
||||
return this.db.getAttribute(key);
|
||||
},
|
||||
set: function(key, value){
|
||||
this.db.setAttribute(key, value);
|
||||
this.db.save(this.project);
|
||||
return value;
|
||||
},
|
||||
rem: function(key){
|
||||
var beforeDelete = this.get(key);
|
||||
this.db.removeAttribute(key);
|
||||
this.db.save(this.project);
|
||||
return beforeDelete;
|
||||
}
|
||||
})
|
||||
|
||||
$.jStore.Engines.ie = jStoreIE;
|
||||
|
||||
// Store the ordering preference
|
||||
$.jStore.EngineOrder[ 4 ] = 'ie';
|
||||
|
||||
})(jQuery);
|
||||
@@ -0,0 +1,476 @@
|
||||
/*
|
||||
http://www.JSON.org/json2.js
|
||||
2009-06-29
|
||||
|
||||
Public Domain.
|
||||
|
||||
NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
|
||||
|
||||
See http://www.JSON.org/js.html
|
||||
|
||||
This file creates a global JSON object containing two methods: stringify
|
||||
and parse.
|
||||
|
||||
JSON.stringify(value, replacer, space)
|
||||
value any JavaScript value, usually an object or array.
|
||||
|
||||
replacer an optional parameter that determines how object
|
||||
values are stringified for objects. It can be a
|
||||
function or an array of strings.
|
||||
|
||||
space an optional parameter that specifies the indentation
|
||||
of nested structures. If it is omitted, the text will
|
||||
be packed without extra whitespace. If it is a number,
|
||||
it will specify the number of spaces to indent at each
|
||||
level. If it is a string (such as '\t' or ' '),
|
||||
it contains the characters used to indent at each level.
|
||||
|
||||
This method produces a JSON text from a JavaScript value.
|
||||
|
||||
When an object value is found, if the object contains a toJSON
|
||||
method, its toJSON method will be called and the result will be
|
||||
stringified. A toJSON method does not serialize: it returns the
|
||||
value represented by the name/value pair that should be serialized,
|
||||
or undefined if nothing should be serialized. The toJSON method
|
||||
will be passed the key associated with the value, and this will be
|
||||
bound to the object holding the key.
|
||||
|
||||
For example, this would serialize Dates as ISO strings.
|
||||
|
||||
Date.prototype.toJSON = function (key) {
|
||||
function f(n) {
|
||||
// Format integers to have at least two digits.
|
||||
return n < 10 ? '0' + n : n;
|
||||
}
|
||||
|
||||
return this.getUTCFullYear() + '-' +
|
||||
f(this.getUTCMonth() + 1) + '-' +
|
||||
f(this.getUTCDate()) + 'T' +
|
||||
f(this.getUTCHours()) + ':' +
|
||||
f(this.getUTCMinutes()) + ':' +
|
||||
f(this.getUTCSeconds()) + 'Z';
|
||||
};
|
||||
|
||||
You can provide an optional replacer method. It will be passed the
|
||||
key and value of each member, with this bound to the containing
|
||||
object. The value that is returned from your method will be
|
||||
serialized. If your method returns undefined, then the member will
|
||||
be excluded from the serialization.
|
||||
|
||||
If the replacer parameter is an array of strings, then it will be
|
||||
used to select the members to be serialized. It filters the results
|
||||
such that only members with keys listed in the replacer array are
|
||||
stringified.
|
||||
|
||||
Values that do not have JSON representations, such as undefined or
|
||||
functions, will not be serialized. Such values in objects will be
|
||||
dropped; in arrays they will be replaced with null. You can use
|
||||
a replacer function to replace those with JSON values.
|
||||
JSON.stringify(undefined) returns undefined.
|
||||
|
||||
The optional space parameter produces a stringification of the
|
||||
value that is filled with line breaks and indentation to make it
|
||||
easier to read.
|
||||
|
||||
If the space parameter is a non-empty string, then that string will
|
||||
be used for indentation. If the space parameter is a number, then
|
||||
the indentation will be that many spaces.
|
||||
|
||||
Example:
|
||||
|
||||
text = JSON.stringify(['e', {pluribus: 'unum'}]);
|
||||
// text is '["e",{"pluribus":"unum"}]'
|
||||
|
||||
|
||||
text = JSON.stringify(['e', {pluribus: 'unum'}], null, '\t');
|
||||
// text is '[\n\t"e",\n\t{\n\t\t"pluribus": "unum"\n\t}\n]'
|
||||
|
||||
text = JSON.stringify([new Date()], function (key, value) {
|
||||
return this[key] instanceof Date ?
|
||||
'Date(' + this[key] + ')' : value;
|
||||
});
|
||||
// text is '["Date(---current time---)"]'
|
||||
|
||||
|
||||
JSON.parse(text, reviver)
|
||||
This method parses a JSON text to produce an object or array.
|
||||
It can throw a SyntaxError exception.
|
||||
|
||||
The optional reviver 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 the structure is not modified.
|
||||
If it returns undefined then the member is deleted.
|
||||
|
||||
Example:
|
||||
|
||||
// Parse the text. Values that look like ISO date strings will
|
||||
// be converted to Date objects.
|
||||
|
||||
myData = JSON.parse(text, function (key, value) {
|
||||
var a;
|
||||
if (typeof value === 'string') {
|
||||
a =
|
||||
/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)Z$/.exec(value);
|
||||
if (a) {
|
||||
return new Date(Date.UTC(+a[1], +a[2] - 1, +a[3], +a[4],
|
||||
+a[5], +a[6]));
|
||||
}
|
||||
}
|
||||
return value;
|
||||
});
|
||||
|
||||
myData = JSON.parse('["Date(09/09/2001)"]', function (key, value) {
|
||||
var d;
|
||||
if (typeof value === 'string' &&
|
||||
value.slice(0, 5) === 'Date(' &&
|
||||
value.slice(-1) === ')') {
|
||||
d = new Date(value.slice(5, -1));
|
||||
if (d) {
|
||||
return d;
|
||||
}
|
||||
}
|
||||
return value;
|
||||
});
|
||||
|
||||
|
||||
This is a reference implementation. You are free to copy, modify, or
|
||||
redistribute.
|
||||
|
||||
This code should be minified before deployment.
|
||||
See http://javascript.crockford.com/jsmin.html
|
||||
|
||||
USE YOUR OWN COPY. IT IS EXTREMELY UNWISE TO LOAD CODE FROM SERVERS YOU DO
|
||||
NOT CONTROL.
|
||||
*/
|
||||
|
||||
/*jslint evil: true */
|
||||
|
||||
/*members "", "\b", "\t", "\n", "\f", "\r", "\"", JSON, "\\", apply,
|
||||
call, charCodeAt, getUTCDate, getUTCFullYear, getUTCHours,
|
||||
getUTCMinutes, getUTCMonth, getUTCSeconds, hasOwnProperty, join,
|
||||
lastIndex, length, parse, prototype, push, replace, slice, stringify,
|
||||
test, toJSON, toString, valueOf
|
||||
*/
|
||||
|
||||
// Create a JSON object only if one does not already exist. We create the
|
||||
// methods in a closure to avoid creating global variables.
|
||||
|
||||
var JSON = 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 isFinite(this.valueOf()) ?
|
||||
this.getUTCFullYear() + '-' +
|
||||
f(this.getUTCMonth() + 1) + '-' +
|
||||
f(this.getUTCDate()) + 'T' +
|
||||
f(this.getUTCHours()) + ':' +
|
||||
f(this.getUTCMinutes()) + ':' +
|
||||
f(this.getUTCSeconds()) + 'Z' : null;
|
||||
};
|
||||
|
||||
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');
|
||||
};
|
||||
}
|
||||
}());
|
||||
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
JSONCookie: Uses JSON to allow the settings of multiple preferences in one cookie.
|
||||
Kanwei Li, 2009
|
||||
|
||||
cookie = new JSONCookie("cookie_name"); // Pass in the name of the cookie
|
||||
|
||||
// Gets the value of a preference, returns optional second argument if pref not found
|
||||
cookie.get("pref", "val_if_not_found");
|
||||
|
||||
cookie.set("pref", "val"); // Sets a value for the preference and saves cookie
|
||||
cookie.unset("pref"); // Unsets the preference and saves cookie
|
||||
cookie.clear() // Deletes the cookie
|
||||
|
||||
*/
|
||||
|
||||
function JSONCookie(name) {
|
||||
this.cookie_name = name;
|
||||
|
||||
}
|
||||
|
||||
JSONCookie.prototype = {
|
||||
json_data : function() {
|
||||
cookie = $.cookie(this.cookie_name);
|
||||
return cookie ? JSON.parse(cookie) : null;
|
||||
},
|
||||
|
||||
save : function(data) {
|
||||
$.cookie(this.cookie_name, JSON.stringify(data));
|
||||
},
|
||||
|
||||
get : function(attr, else_val) {
|
||||
data = this.json_data();
|
||||
if (data && data[attr]) { return data[attr];
|
||||
} else if (else_val) { return else_val;
|
||||
} else { return null;
|
||||
}
|
||||
},
|
||||
|
||||
set : function(attr, val) {
|
||||
data = this.json_data();
|
||||
if (data) {
|
||||
data[attr] = val;
|
||||
} else {
|
||||
data = { attr : val }
|
||||
}
|
||||
this.save(data);
|
||||
},
|
||||
|
||||
unset : function(attr) {
|
||||
data = this.json_data();
|
||||
if (data) {
|
||||
delete data[attr];
|
||||
}
|
||||
this.save(data);
|
||||
},
|
||||
|
||||
clear : function() {
|
||||
this.save(null);
|
||||
}
|
||||
|
||||
};
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* jStore - Persistent Client-Side Storage
|
||||
*
|
||||
* Copyright (c) 2009 Eric Garside (http://eric.garside.name)
|
||||
*
|
||||
* Dual licensed under:
|
||||
* MIT: http://www.opensource.org/licenses/mit-license.php
|
||||
* GPLv3: http://www.opensource.org/licenses/gpl-3.0.html
|
||||
*/
|
||||
(function(){var a=false,b=/xyz/.test(function(){xyz})?/\b_super\b/:/.*/;this.Class=function(){};Class.extend=function(g){var f=this.prototype;a=true;var e=new this();a=false;for(var d in g){e[d]=typeof g[d]=="function"&&typeof f[d]=="function"&&b.test(g[d])?(function(h,i){return function(){var k=this._super;this._super=f[h];var j=i.apply(this,arguments);this._super=k;return j}})(d,g[d]):g[d]}function c(){if(!a&&this.init){this.init.apply(this,arguments)}}c.prototype=e;c.constructor=c;c.extend=arguments.callee;return c}})();
|
||||
/*
|
||||
* jStore Delegate Framework
|
||||
* Copyright (c) 2009 Eric Garside (http://eric.garside.name)
|
||||
*/
|
||||
(function(a){this.jStoreDelegate=Class.extend({init:function(b){this.parent=b;this.callbacks={}},bind:function(b,c){if(!a.isFunction(c)){return this}if(!this.callbacks[b]){this.callbacks[b]=[]}this.callbacks[b].push(c);return this},trigger:function(){var d=this.parent,c=[].slice.call(arguments),e=c.shift(),b=this.callbacks[e];if(!b){return false}a.each(b,function(){this.apply(d,c)});return this}})})(jQuery);(function(a){a.jStore={};a.extend(a.jStore,{EngineOrder:[],Availability:{},Engines:{},Instances:{},CurrentEngine:null,defaults:{project:null,engine:null,autoload:true,flash:"jStore.Flash.html"},isReady:false,isFlashReady:false,delegate:new jStoreDelegate(a.jStore).bind("jStore-ready",function(b){a.jStore.isReady=true;if(a.jStore.defaults.autoload){b.connect()}}).bind("flash-ready",function(){a.jStore.isFlashReady=true})});a.jStore.ready=function(b){if(a.jStore.isReady){b.apply(a.jStore,[a.jStore.CurrentEngine])}else{a.jStore.delegate.bind("jStore-ready",b)}};a.jStore.fail=function(b){a.jStore.delegate.bind("jStore-failure",b)};a.jStore.flashReady=function(b){if(a.jStore.isFlashReady){b.apply(a.jStore,[a.jStore.CurrentEngine])}else{a.jStore.delegate.bind("flash-ready",b)}};a.jStore.use=function(d,g,c){g=g||a.jStore.defaults.project||location.hostname.replace(/\./g,"-")||"unknown";var f=a.jStore.Engines[d.toLowerCase()]||null,b=(c?c+".":"")+g+"."+d;if(!f){throw"JSTORE_ENGINE_UNDEFINED"}f=new f(g,b);if(a.jStore.Instances[b]){throw"JSTORE_JRI_CONFLICT"}if(f.isAvailable()){a.jStore.Instances[b]=f;if(!a.jStore.CurrentEngine){a.jStore.CurrentEngine=f}a.jStore.delegate.trigger("jStore-ready",f)}else{if(!f.autoload){throw"JSTORE_ENGINE_UNAVILABLE"}else{f.included(function(){if(this.isAvailable()){a.jStore.Instances[b]=this;if(!a.jStore.CurrentEngine){a.jStore.CurrentEngine=this}a.jStore.delegate.trigger("jStore-ready",this)}else{a.jStore.delegate.trigger("jStore-failure",this)}}).include()}}};a.jStore.setCurrentEngine=function(b){if(!a.jStore.Instances.length){return a.jStore.FindEngine()}if(!b&&a.jStore.Instances.length>=1){a.jStore.delegate.trigger("jStore-ready",a.jStore.Instances[0]);return a.jStore.CurrentEngine=a.jStore.Instances[0]}if(b&&a.jStore.Instances[b]){a.jStore.delegate.trigger("jStore-ready",a.jStore.Instances[b]);return a.jStore.CurrentEngine=a.jStore.Instances[b]}throw"JSTORE_JRI_NO_MATCH"};a.jStore.FindEngine=function(){a.each(a.jStore.EngineOrder,function(b){if(a.jStore.Availability[this]()){a.jStore.use(this,a.jStore.defaults.project,"default");return false}})};a.jStore.store=function(b,c){if(!a.jStore.CurrentEngine){return false}if(!c){return a.jStore.CurrentEngine.get(b)}return a.jStore.CurrentEngine.set(b,c)};a.jStore.remove=function(b){if(!a.jStore.CurrentEngine){return false}return a.jStore.CurrentEngine.rem(b)};a.fn.store=function(c,d){if(!a.jStore.CurrentEngine){return this}var b=a.jStore.store(c,d);return !d?b:this};a.fn.removeStore=function(b){a.jStore.remove(b);return this};a.jStore.load=function(){if(a.jStore.defaults.engine){return a.jStore.use(a.jStore.defaults.engine,a.jStore.defaults.project,"default")}try{a.jStore.FindEngine()}catch(b){}}})(jQuery);(function(a){this.StorageEngine=Class.extend({init:function(c,b){this.project=c;this.jri=b;this.data={};this.limit=-1;this.includes=[];this.delegate=new jStoreDelegate(this).bind("engine-ready",function(){this.isReady=true}).bind("engine-included",function(){this.hasIncluded=true});this.autoload=false;this.isReady=false;this.hasIncluded=false},include:function(){var b=this,d=this.includes.length,c=0;a.each(this.includes,function(){a.ajax({type:"get",url:this,dataType:"script",cache:true,success:function(){c++;if(c==d){b.delegate.trigger("engine-included")}}})})},isAvailable:function(){return false},ready:function(b){if(this.isReady){b.apply(this)}else{this.delegate.bind("engine-ready",b)}return this},included:function(b){if(this.hasIncluded){b.apply(this)}else{this.delegate.bind("engine-included",b)}return this},get:function(b){return this.data[b]||null},set:function(b,c){this.data[b]=c;return c},rem:function(b){var c=this.data[b];this.data[b]=null;return c}})})(jQuery);
|
||||
/*
|
||||
* jStore DOM Storage Engine
|
||||
* Copyright (c) 2009 Eric Garside (http://eric.garside.name)
|
||||
*/
|
||||
(function(c){var b=c.jStore.Availability.session=function(){return !!window.sessionStorage},a=c.jStore.Availability.local=function(){return !!(window.localStorage||window.globalStorage)};this.jStoreDom=StorageEngine.extend({init:function(e,d){this._super(e,d);this.type="DOM";this.limit=5*1024*1024},connect:function(){this.delegate.trigger("engine-ready")},get:function(e){var d=this.db.getItem(e);return d&&d.value?d.value:d},set:function(d,e){this.db.setItem(d,e);return e},rem:function(e){var d=this.get(e);this.db.removeItem(e);return d}});this.jStoreLocal=jStoreDom.extend({connect:function(){this.db=!window.globalStorage?window.localStorage:window.globalStorage[location.hostname];this._super()},isAvailable:a});this.jStoreSession=jStoreDom.extend({connect:function(){this.db=sessionStorage;this._super()},isAvailable:b});c.jStore.Engines.local=jStoreLocal;c.jStore.Engines.session=jStoreSession;c.jStore.EngineOrder[1]="local"})(jQuery);
|
||||
/*
|
||||
* jStore Flash Storage Engine
|
||||
* Copyright (c) 2009 Eric Garside (http://eric.garside.name)
|
||||
* jStore.swf Copyright (c) 2008 Daniel Bulli (http://www.nuff-respec.com)
|
||||
*/
|
||||
(function(b){var a=b.jStore.Availability.flash=function(){return !!(b.jStore.hasFlash("8.0.0"))};this.jStoreFlash=StorageEngine.extend({init:function(e,d){this._super(e,d);this.type="Flash";var c=this;b.jStore.flashReady(function(){c.flashReady()})},connect:function(){var c="jstore-flash-embed-"+this.project;b(document.body).append('<iframe style="height:1px;width:1px;position:absolute;left:0;top:0;margin-left:-100px;" id="jStoreFlashFrame" src="'+b.jStore.defaults.flash+'"></iframe>')},flashReady:function(f){var c=b("#jStoreFlashFrame")[0];if(c.Document&&b.isFunction(c.Document.jStoreFlash.f_get_cookie)){this.db=c.Document.jStoreFlash}else{if(c.contentWindow&&c.contentWindow.document){var d=c.contentWindow.document;if(b.isFunction(b("object",b(d))[0].f_get_cookie)){this.db=b("object",b(d))[0]}else{if(b.isFunction(b("embed",b(d))[0].f_get_cookie)){this.db=b("embed",b(d))[0]}}}}if(this.db){this.delegate.trigger("engine-ready")}},isAvailable:a,get:function(d){var c=this.db.f_get_cookie(d);return c=="null"?null:c},set:function(c,d){this.db.f_set_cookie(c,d);return d},rem:function(c){var d=this.get(c);this.db.f_delete_cookie(c);return d}});b.jStore.Engines.flash=jStoreFlash;b.jStore.EngineOrder[2]="flash";b.jStore.hasFlash=function(c){var e=b.jStore.flashVersion().match(/\d+/g),f=c.match(/\d+/g);for(var d=0;d<3;d++){e[d]=parseInt(e[d]||0);f[d]=parseInt(f[d]||0);if(e[d]<f[d]){return false}if(e[d]>f[d]){return true}}return true};b.jStore.flashVersion=function(){try{try{var c=new ActiveXObject("ShockwaveFlash.ShockwaveFlash.6");try{c.AllowScriptAccess="always"}catch(d){return"6,0,0"}}catch(d){}return new ActiveXObject("ShockwaveFlash.ShockwaveFlash").GetVariable("$version").replace(/\D+/g,",").match(/^,?(.+),?$/)[1]}catch(d){try{if(navigator.mimeTypes["application/x-shockwave-flash"].enabledPlugin){return(navigator.plugins["Shockwave Flash 2.0"]||navigator.plugins["Shockwave Flash"]).description.replace(/\D+/g,",").match(/^,?(.+),?$/)[1]}}catch(d){}}return"0,0,0"}})(jQuery);function flash_ready(){$.jStore.delegate.trigger("flash-ready")}
|
||||
/*
|
||||
* jStore Google Gears Storage Engine
|
||||
* Copyright (c) 2009 Eric Garside (http://eric.garside.name)
|
||||
*/
|
||||
(function(b){var a=b.jStore.Availability.gears=function(){return !!(window.google&&window.google.gears)};this.jStoreGears=StorageEngine.extend({init:function(d,c){this._super(d,c);this.type="Google Gears";this.includes.push("http://code.google.com/apis/gears/gears_init.js");this.autoload=true},connect:function(){var c=this.db=google.gears.factory.create("beta.database");c.open("jstore-"+this.project);c.execute("CREATE TABLE IF NOT EXISTS jstore (k TEXT UNIQUE NOT NULL PRIMARY KEY, v TEXT NOT NULL)");this.updateCache()},updateCache:function(){var c=this.db.execute("SELECT k,v FROM jstore");while(c.isValidRow()){this.data[c.field(0)]=c.field(1);c.next()}c.close();this.delegate.trigger("engine-ready")},isAvailable:a,set:function(d,e){var c=this.db;c.execute("BEGIN");c.execute("INSERT OR REPLACE INTO jstore(k, v) VALUES (?, ?)",[d,e]);c.execute("COMMIT");return this._super(d,e)},rem:function(d){var c=this.db;c.execute("BEGIN");c.execute("DELETE FROM jstore WHERE k = ?",[d]);c.execute("COMMIT");return this._super(d)}});b.jStore.Engines.gears=jStoreGears;b.jStore.EngineOrder[3]="gears"})(jQuery);
|
||||
/*
|
||||
* jStore HTML5 Specification Storage Engine
|
||||
* Copyright (c) 2009 Eric Garside (http://eric.garside.name)
|
||||
*/
|
||||
(function(b){var a=b.jStore.Availability.html5=function(){return !!window.openDatabase};this.jStoreHtml5=StorageEngine.extend({init:function(d,c){this._super(d,c);this.type="HTML5";this.limit=1024*200},connect:function(){var c=this.db=openDatabase("jstore-"+this.project,"1.0",this.project,this.limit);if(!c){throw"JSTORE_ENGINE_HTML5_NODB"}c.transaction(function(d){d.executeSql("CREATE TABLE IF NOT EXISTS jstore (k TEXT UNIQUE NOT NULL PRIMARY KEY, v TEXT NOT NULL)")});this.updateCache()},updateCache:function(){var c=this;this.db.transaction(function(d){d.executeSql("SELECT k,v FROM jstore",[],function(f,e){var h=e.rows,g=0,j;for(;g<h.length;++g){j=h.item(g);c.data[j.k]=j.v}c.delegate.trigger("engine-ready")})})},isAvailable:a,set:function(c,d){this.db.transaction(function(e){e.executeSql("INSERT OR REPLACE INTO jstore(k, v) VALUES (?, ?)",[c,d])});return this._super(c,d)},rem:function(c){this.db.transaction(function(d){d.executeSql("DELETE FROM jstore WHERE k = ?",[c])});return this._super(c)}});b.jStore.Engines.html5=jStoreHtml5;b.jStore.EngineOrder[0]="html5"})(jQuery);
|
||||
/**
|
||||
* jStore IE Storage Engine
|
||||
* Copyright (c) 2009 Eric Garside (http://eric.garside.name)
|
||||
*/
|
||||
(function(b){var a=b.jStore.Availability.ie=function(){return !!window.ActiveXObject};this.jStoreIE=StorageEngine.extend({init:function(d,c){this._super(d,c);this.type="IE";this.limit=64*1024},connect:function(){this.db=b('<div style="display:none;behavior:url(\'#default#userData\')" id="jstore-'+this.project+'"></div>').appendTo(document.body).get(0);this.delegate.trigger("engine-ready")},isAvailable:a,get:function(c){this.db.load(this.project);return this.db.getAttribute(c)},set:function(c,d){this.db.setAttribute(c,d);this.db.save(this.project);return d},rem:function(c){var d=this.get(c);this.db.removeAttribute(c);this.db.save(this.project);return d}});b.jStore.Engines.ie=jStoreIE;b.jStore.EngineOrder[4]="ie"})(jQuery);
|
||||
@@ -0,0 +1 @@
|
||||
var JSON=JSON||{};(function(){function f(n){return n<10?"0"+n:n}if(typeof Date.prototype.toJSON!=="function"){Date.prototype.toJSON=function(key){return isFinite(this.valueOf())?this.getUTCFullYear()+"-"+f(this.getUTCMonth()+1)+"-"+f(this.getUTCDate())+"T"+f(this.getUTCHours())+":"+f(this.getUTCMinutes())+":"+f(this.getUTCSeconds())+"Z":null};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={"\b":"\\b","\t":"\\t","\n":"\\n","\f":"\\f","\r":"\\r",'"':'\\"',"\\":"\\\\"},rep;function quote(string){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){var i,k,v,length,mind=gap,partial,value=holder[key];if(value&&typeof value==="object"&&typeof value.toJSON==="function"){value=value.toJSON(key)}if(typeof rep==="function"){value=rep.call(holder,key,value)}switch(typeof value){case"string":return quote(value);case"number":return isFinite(value)?String(value):"null";case"boolean":case"null":return String(value);case"object":if(!value){return"null"}gap+=indent;partial=[];if(Object.prototype.toString.apply(value)==="[object Array]"){length=value.length;for(i=0;i<length;i+=1){partial[i]=str(i,value)||"null"}v=partial.length===0?"[]":gap?"[\n"+gap+partial.join(",\n"+gap)+"\n"+mind+"]":"["+partial.join(",")+"]";gap=mind;return v}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{for(k in value){if(Object.hasOwnProperty.call(value,k)){v=str(k,value);if(v){partial.push(quote(k)+(gap?": ":":")+v)}}}}v=partial.length===0?"{}":gap?"{\n"+gap+partial.join(",\n"+gap)+"\n"+mind+"}":"{"+partial.join(",")+"}";gap=mind;return v}}if(typeof JSON.stringify!=="function"){JSON.stringify=function(value,replacer,space){var i;gap="";indent="";if(typeof space==="number"){for(i=0;i<space;i+=1){indent+=" "}}else{if(typeof space==="string"){indent=space}}rep=replacer;if(replacer&&typeof replacer!=="function"&&(typeof replacer!=="object"||typeof replacer.length!=="number")){throw new Error("JSON.stringify")}return str("",{"":value})}}if(typeof JSON.parse!=="function"){JSON.parse=function(text,reviver){var j;function walk(holder,key){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)}cx.lastIndex=0;if(cx.test(text)){text=text.replace(cx,function(a){return"\\u"+("0000"+a.charCodeAt(0).toString(16)).slice(-4)})}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,""))){j=eval("("+text+")");return typeof reviver==="function"?walk({"":j},""):j}throw new SyntaxError("JSON.parse")}}}());
|
||||
+228
-205
@@ -15,219 +15,242 @@
|
||||
<meta http-equiv="Pragma" content="no-cache">
|
||||
|
||||
${h.css( "base", "history" )}
|
||||
${h.js( "jquery", "jquery.cookie", "cookie_set" )}
|
||||
|
||||
${h.js( "jquery", "json2", "jquery.jstore-all" )}
|
||||
|
||||
<script type="text/javascript">
|
||||
$( document ).ready( function() {
|
||||
initShowHide();
|
||||
setupHistoryItem( $("div.historyItemWrapper") );
|
||||
// Collapse all
|
||||
$("#top-links").append( "| " ).append( $("<a href='#'>${_('collapse all')}</a>").click( function() {
|
||||
$( "div.historyItemBody:visible" ).each( function() {
|
||||
if ( $.browser.mozilla )
|
||||
{
|
||||
$(this).find( "pre.peek" ).css( "overflow", "hidden" );
|
||||
}
|
||||
$(this).slideUp( "fast" );
|
||||
})
|
||||
var state = new CookieSet( "galaxy.history.expand_state" );
|
||||
state.removeAll().save();
|
||||
return false;
|
||||
}));
|
||||
$("#history-rename").click( function() {
|
||||
var old_name = $("#history-name").text()
|
||||
var t = $("<input type='text' value='" + old_name + "'></input>" );
|
||||
t.blur( function() {
|
||||
$(this).remove();
|
||||
$("#history-name").show();
|
||||
});
|
||||
t.keyup( function( e ) {
|
||||
if ( e.keyCode == 27 ) {
|
||||
// Escape key
|
||||
$(this).trigger( "blur" );
|
||||
} else if ( e.keyCode == 13 ) {
|
||||
// Enter key
|
||||
new_value = this.value;
|
||||
$(this).trigger( "blur" );
|
||||
$.ajax({
|
||||
url: "${h.url_for( controller='history', action='rename_async', id=history.id )}",
|
||||
data: { "_": true, new_name: new_value },
|
||||
error: function() { alert( "Rename failed" ) },
|
||||
success: function() {
|
||||
$("#history-name").text( new_value );
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
$("#history-name").hide();
|
||||
$("#history-name-area").append( t );
|
||||
t.focus();
|
||||
return false;
|
||||
});
|
||||
// Updater
|
||||
updater({
|
||||
%for i, data in enumerate( reversed( datasets ) ):
|
||||
%if data.visible and data.state not in [ "deleted", "empty", "error", "ok" ]:
|
||||
%if i > 0:
|
||||
,
|
||||
%endif
|
||||
"${data.id}": "${data.state}"
|
||||
%endif
|
||||
%endfor
|
||||
$(function() {
|
||||
// Load jStore for local storage
|
||||
$.extend(jQuery.jStore.defaults, { project: 'galaxy', flash: '/static/jStore.Flash.html' })
|
||||
$.jStore.load(); // Auto-select best storage
|
||||
|
||||
$.jStore.ready(function(engine) {
|
||||
engine.ready(function() {
|
||||
// Init stuff that requires the local storage to be running
|
||||
initShowHide();
|
||||
setupHistoryItem( $("div.historyItemWrapper") );
|
||||
});
|
||||
})
|
||||
//' Functionized so AJAX'd datasets can call them
|
||||
// Get shown/hidden state from cookie
|
||||
function initShowHide() {
|
||||
// $( "div.historyItemBody" ).hide();
|
||||
// Load saved state and show as neccesary
|
||||
var state = new CookieSet( "galaxy.history.expand_state" );
|
||||
for ( id in state.store ) {
|
||||
if ( id ) {
|
||||
$( "#" + id + " div.historyItemBody" ).show();
|
||||
}
|
||||
}
|
||||
// If Mozilla, hide scrollbars in hidden items since they cause animation bugs
|
||||
if ( $.browser.mozilla ) {
|
||||
$( "div.historyItemBody" ).each( function() {
|
||||
if ( ! $(this).is( ":visible" ) ) $(this).find( "pre.peek" ).css( "overflow", "hidden" );
|
||||
})
|
||||
}
|
||||
delete state;
|
||||
}
|
||||
// Add show/hide link and delete link to a history item
|
||||
function setupHistoryItem( query ) {
|
||||
query.each( function() {
|
||||
var id = this.id;
|
||||
var body = $(this).children( "div.historyItemBody" );
|
||||
var peek = body.find( "pre.peek" )
|
||||
$(this).children( ".historyItemTitleBar" ).find( ".historyItemTitle" ).wrap( "<a href='#'></a>" ).click( function() {
|
||||
if ( body.is(":visible") ) {
|
||||
if ( $.browser.mozilla ) { peek.css( "overflow", "hidden" ) }
|
||||
body.slideUp( "fast" );
|
||||
## other instances of this could be editing the cookie, refetch
|
||||
var state = new CookieSet( "galaxy.history.expand_state" );
|
||||
state.remove( id ); state.save();
|
||||
delete state;
|
||||
}
|
||||
else {
|
||||
body.slideDown( "fast", function() {
|
||||
if ( $.browser.mozilla ) { peek.css( "overflow", "auto" ); }
|
||||
});
|
||||
var state = new CookieSet( "galaxy.history.expand_state" );
|
||||
state.add( id ); state.save();
|
||||
delete state;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
// Delete link
|
||||
$(this).find( "div.historyItemButtons > .delete" ).each( function() {
|
||||
var data_id = this.id.split( "-" )[1];
|
||||
$(this).click( function() {
|
||||
$( '#historyItem-' + data_id + "> div.historyItemTitleBar" ).addClass( "spinner" );
|
||||
$.ajax({
|
||||
url: "${h.url_for( action='delete_async', id='XXX' )}".replace( 'XXX', data_id ),
|
||||
error: function() { alert( "Delete failed" ) },
|
||||
success: function() {
|
||||
%if show_deleted:
|
||||
var to_update = {};
|
||||
to_update[data_id] = "none";
|
||||
updater( to_update );
|
||||
%else:
|
||||
$( "#historyItem-" + data_id ).fadeOut( "fast", function() {
|
||||
$( "#historyItemContainer-" + data_id ).remove();
|
||||
if ( $( "div.historyItemContainer" ).length < 1 ) {
|
||||
$( "#emptyHistoryMessage" ).show();
|
||||
}
|
||||
});
|
||||
%endif
|
||||
}
|
||||
});
|
||||
return false;
|
||||
});
|
||||
});
|
||||
// Undelete link
|
||||
$(this).find( "a.historyItemUndelete" ).each( function() {
|
||||
var data_id = this.id.split( "-" )[1];
|
||||
$(this).click( function() {
|
||||
$( '#historyItem-' + data_id + " > div.historyItemTitleBar" ).addClass( "spinner" );
|
||||
$.ajax({
|
||||
url: "${h.url_for( controller='dataset', action='undelete_async', id='XXX' )}".replace( 'XXX', data_id ),
|
||||
error: function() { alert( "Undelete failed" ) },
|
||||
success: function() {
|
||||
var to_update = {};
|
||||
to_update[data_id] = "none";
|
||||
updater( to_update );
|
||||
}
|
||||
});
|
||||
return false;
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// Generate 'collapse all' link
|
||||
$("#top-links").append( "| " ).append( $("<a href='#'>${_('collapse all')}</a>").click( function() {
|
||||
$( "div.historyItemBody:visible" ).each( function() {
|
||||
if ( $.browser.mozilla ) {
|
||||
$(this).find( "pre.peek" ).css( "overflow", "hidden" );
|
||||
}
|
||||
$(this).slideUp( "fast" );
|
||||
});
|
||||
};
|
||||
// Looks for changes in dataset state using an async request. Keeps
|
||||
// calling itself (via setTimeout) until all datasets are in a terminal
|
||||
// state.
|
||||
var updater = function ( tracked_datasets ) {
|
||||
// Check if there are any items left to track
|
||||
var empty = true;
|
||||
for ( i in tracked_datasets ) {
|
||||
empty = false;
|
||||
break;
|
||||
}
|
||||
if ( ! empty ) {
|
||||
// console.log( "Updater running in 3 seconds" );
|
||||
setTimeout( function() { updater_callback( tracked_datasets ) }, 3000 );
|
||||
} else {
|
||||
// console.log( "Updater finished" );
|
||||
}
|
||||
};
|
||||
var updater_callback = function ( tracked_datasets ) {
|
||||
// Build request data
|
||||
var ids = []
|
||||
var states = []
|
||||
var force_history_refresh = false
|
||||
$.each( tracked_datasets, function ( id, state ) {
|
||||
ids.push( id );
|
||||
states.push( state );
|
||||
$.jStore.remove("history_expand_state");
|
||||
}));
|
||||
|
||||
$("#history-rename").click( function() {
|
||||
var old_name = $("#history-name").text()
|
||||
var t = $("<input type='text' value='" + old_name + "'></input>" );
|
||||
t.blur( function() {
|
||||
$(this).remove();
|
||||
$("#history-name").show();
|
||||
});
|
||||
// Make ajax call
|
||||
$.ajax( {
|
||||
type: "POST",
|
||||
url: "${h.url_for( controller='root', action='history_item_updates' )}",
|
||||
dataType: "json",
|
||||
data: { ids: ids.join( "," ), states: states.join( "," ) },
|
||||
success : function ( data ) {
|
||||
$.each( data, function( id, val ) {
|
||||
// Replace HTML
|
||||
var container = $("#historyItemContainer-" + id);
|
||||
container.html( val.html );
|
||||
setupHistoryItem( container.children( ".historyItemWrapper" ) );
|
||||
initShowHide();
|
||||
// If new state was terminal, stop tracking
|
||||
if (( val.state == "ok") || ( val.state == "error") || ( val.state == "empty") || ( val.state == "deleted" ) || ( val.state == "discarded" )) {
|
||||
if ( val.force_history_refresh ){
|
||||
force_history_refresh = true;
|
||||
}
|
||||
delete tracked_datasets[ parseInt(id) ];
|
||||
} else {
|
||||
tracked_datasets[ parseInt(id) ] = val.state;
|
||||
t.keyup( function( e ) {
|
||||
if ( e.keyCode == 27 ) {
|
||||
// Escape key
|
||||
$(this).trigger( "blur" );
|
||||
} else if ( e.keyCode == 13 ) {
|
||||
// Enter key
|
||||
new_value = this.value;
|
||||
$(this).trigger( "blur" );
|
||||
$.ajax({
|
||||
url: "${h.url_for( controller='history', action='rename_async', id=history.id )}",
|
||||
data: { "_": true, new_name: new_value },
|
||||
error: function() { alert( "Rename failed" ) },
|
||||
success: function() {
|
||||
$("#history-name").text( new_value );
|
||||
}
|
||||
});
|
||||
if ( force_history_refresh ) {
|
||||
parent.frames.galaxy_history.location.reload();
|
||||
}
|
||||
else {
|
||||
// Keep going (if there are still any items to track)
|
||||
updater( tracked_datasets );
|
||||
}
|
||||
},
|
||||
error: function() {
|
||||
// Just retry, like the old method, should try to be smarter
|
||||
updater( tracked_datasets );
|
||||
}
|
||||
});
|
||||
};
|
||||
$("#history-name").hide();
|
||||
$("#history-name-area").append( t );
|
||||
t.focus();
|
||||
return false;
|
||||
});
|
||||
// Updater
|
||||
updater({
|
||||
%for i, data in enumerate( reversed( datasets ) ):
|
||||
%if data.visible and data.state not in [ "deleted", "empty", "error", "ok" ]:
|
||||
%if i > 0:
|
||||
,
|
||||
%endif
|
||||
"${data.id}": "${data.state}"
|
||||
%endif
|
||||
%endfor
|
||||
});
|
||||
});
|
||||
// Functionized so AJAX'd datasets can call them
|
||||
// Get shown/hidden state from cookie
|
||||
function initShowHide() {
|
||||
|
||||
// Load saved state and show as neccesary
|
||||
try {
|
||||
var stored = $.jStore.store("history_expand_state");
|
||||
if (stored) {
|
||||
var st = JSON.parse(stored);
|
||||
for (var id in st) {
|
||||
$("#" + id + " div.historyItemBody" ).show();
|
||||
}
|
||||
}
|
||||
} catch(err) {
|
||||
// Something was wrong with values in storage, so clear storage
|
||||
$.jStore.remove("history_expand_state");
|
||||
}
|
||||
|
||||
// If Mozilla, hide scrollbars in hidden items since they cause animation bugs
|
||||
if ( $.browser.mozilla ) {
|
||||
$( "div.historyItemBody" ).each( function() {
|
||||
if ( ! $(this).is( ":visible" ) ) $(this).find( "pre.peek" ).css( "overflow", "hidden" );
|
||||
})
|
||||
}
|
||||
}
|
||||
// Add show/hide link and delete link to a history item
|
||||
function setupHistoryItem( query ) {
|
||||
query.each( function() {
|
||||
var id = this.id;
|
||||
var body = $(this).children( "div.historyItemBody" );
|
||||
var peek = body.find( "pre.peek" )
|
||||
$(this).children( ".historyItemTitleBar" ).find( ".historyItemTitle" ).wrap( "<a href='#'></a>" ).click( function() {
|
||||
if ( body.is(":visible") ) {
|
||||
// Hiding stuff here
|
||||
if ( $.browser.mozilla ) { peek.css( "overflow", "hidden" ) }
|
||||
body.slideUp( "fast" );
|
||||
|
||||
// Save setting
|
||||
var stored = $.jStore.store("history_expand_state")
|
||||
var prefs = stored ? JSON.parse(stored) : null
|
||||
if (prefs) {
|
||||
delete prefs[id];
|
||||
$.jStore.store("history_expand_state", JSON.stringify(prefs));
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Showing stuff here
|
||||
body.slideDown( "fast", function() {
|
||||
if ( $.browser.mozilla ) { peek.css( "overflow", "auto" ); }
|
||||
});
|
||||
|
||||
// Save setting
|
||||
var stored = $.jStore.store("history_expand_state")
|
||||
var prefs = stored ? JSON.parse(stored) : new Object;
|
||||
prefs[id] = true;
|
||||
$.jStore.store("history_expand_state", JSON.stringify(prefs));
|
||||
}
|
||||
return false;
|
||||
});
|
||||
// Delete link
|
||||
$(this).find( "div.historyItemButtons > .delete" ).each( function() {
|
||||
var data_id = this.id.split( "-" )[1];
|
||||
$(this).click( function() {
|
||||
$( '#historyItem-' + data_id + "> div.historyItemTitleBar" ).addClass( "spinner" );
|
||||
$.ajax({
|
||||
url: "${h.url_for( action='delete_async', id='XXX' )}".replace( 'XXX', data_id ),
|
||||
error: function() { alert( "Delete failed" ) },
|
||||
success: function() {
|
||||
%if show_deleted:
|
||||
var to_update = {};
|
||||
to_update[data_id] = "none";
|
||||
updater( to_update );
|
||||
%else:
|
||||
$( "#historyItem-" + data_id ).fadeOut( "fast", function() {
|
||||
$( "#historyItemContainer-" + data_id ).remove();
|
||||
if ( $( "div.historyItemContainer" ).length < 1 ) {
|
||||
$( "#emptyHistoryMessage" ).show();
|
||||
}
|
||||
});
|
||||
%endif
|
||||
}
|
||||
});
|
||||
return false;
|
||||
});
|
||||
});
|
||||
// Undelete link
|
||||
$(this).find( "a.historyItemUndelete" ).each( function() {
|
||||
var data_id = this.id.split( "-" )[1];
|
||||
$(this).click( function() {
|
||||
$( '#historyItem-' + data_id + " > div.historyItemTitleBar" ).addClass( "spinner" );
|
||||
$.ajax({
|
||||
url: "${h.url_for( controller='dataset', action='undelete_async', id='XXX' )}".replace( 'XXX', data_id ),
|
||||
error: function() { alert( "Undelete failed" ) },
|
||||
success: function() {
|
||||
var to_update = {};
|
||||
to_update[data_id] = "none";
|
||||
updater( to_update );
|
||||
}
|
||||
});
|
||||
return false;
|
||||
});
|
||||
});
|
||||
});
|
||||
};
|
||||
// Looks for changes in dataset state using an async request. Keeps
|
||||
// calling itself (via setTimeout) until all datasets are in a terminal
|
||||
// state.
|
||||
var updater = function ( tracked_datasets ) {
|
||||
// Check if there are any items left to track
|
||||
var empty = true;
|
||||
for ( i in tracked_datasets ) {
|
||||
empty = false;
|
||||
break;
|
||||
}
|
||||
if ( ! empty ) {
|
||||
// console.log( "Updater running in 3 seconds" );
|
||||
setTimeout( function() { updater_callback( tracked_datasets ) }, 3000 );
|
||||
} else {
|
||||
// console.log( "Updater finished" );
|
||||
}
|
||||
};
|
||||
var updater_callback = function ( tracked_datasets ) {
|
||||
// Build request data
|
||||
var ids = []
|
||||
var states = []
|
||||
var force_history_refresh = false
|
||||
$.each( tracked_datasets, function ( id, state ) {
|
||||
ids.push( id );
|
||||
states.push( state );
|
||||
});
|
||||
// Make ajax call
|
||||
$.ajax( {
|
||||
type: "POST",
|
||||
url: "${h.url_for( controller='root', action='history_item_updates' )}",
|
||||
dataType: "json",
|
||||
data: { ids: ids.join( "," ), states: states.join( "," ) },
|
||||
success : function ( data ) {
|
||||
$.each( data, function( id, val ) {
|
||||
// Replace HTML
|
||||
var container = $("#historyItemContainer-" + id);
|
||||
container.html( val.html );
|
||||
setupHistoryItem( container.children( ".historyItemWrapper" ) );
|
||||
initShowHide();
|
||||
// If new state was terminal, stop tracking
|
||||
if (( val.state == "ok") || ( val.state == "error") || ( val.state == "empty") || ( val.state == "deleted" ) || ( val.state == "discarded" )) {
|
||||
if ( val.force_history_refresh ){
|
||||
force_history_refresh = true;
|
||||
}
|
||||
delete tracked_datasets[ parseInt(id) ];
|
||||
} else {
|
||||
tracked_datasets[ parseInt(id) ] = val.state;
|
||||
}
|
||||
});
|
||||
if ( force_history_refresh ) {
|
||||
parent.frames.galaxy_history.location.reload();
|
||||
}
|
||||
else {
|
||||
// Keep going (if there are still any items to track)
|
||||
updater( tracked_datasets );
|
||||
}
|
||||
},
|
||||
error: function() {
|
||||
// Just retry, like the old method, should try to be smarter
|
||||
updater( tracked_datasets );
|
||||
}
|
||||
});
|
||||
};
|
||||
</script>
|
||||
|
||||
<style>
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
<script type='text/javascript' src="${h.url_for('/static/scripts/jquery.event.hover.js')}"> </script>
|
||||
<script type='text/javascript' src="${h.url_for('/static/scripts/jquery.form.js')}"> </script>
|
||||
<script type='text/javascript' src="${h.url_for('/static/scripts/jquery.json.js')}"> </script>
|
||||
<script type='text/javascript' src="${h.url_for('/static/scripts/jquery.jstore-all.js')}"> </script>
|
||||
|
||||
<script type='text/javascript' src="${h.url_for('/static/scripts/galaxy.base.js')}"> </script>
|
||||
<script type='text/javascript' src="${h.url_for('/static/scripts/galaxy.workflow_editor.canvas.js')}"> </script>
|
||||
@@ -47,6 +48,7 @@
|
||||
canvas_manager = null;
|
||||
// jQuery onReady
|
||||
$( function() {
|
||||
|
||||
if ( window.lt_ie_7 ) {
|
||||
show_modal(
|
||||
"Browser not supported",
|
||||
@@ -54,8 +56,14 @@
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
// Load jStore for local storage
|
||||
$.extend(jQuery.jStore.defaults, { project: 'galaxy', flash: '/static/jStore.Flash.html' })
|
||||
$.jStore.load(); // Auto-select best storage
|
||||
|
||||
// Canvas overview management
|
||||
canvas_manager = new CanvasManager( $("#canvas-viewport"), $("#overview") );
|
||||
|
||||
// Initialize workflow state
|
||||
reset();
|
||||
// Load the datatype info
|
||||
@@ -121,17 +129,46 @@
|
||||
canvas_manager.draw_overview();
|
||||
});
|
||||
|
||||
/* Lets the viewport be toggled visible and invisible, adjusting the arrows accordingly */
|
||||
$("#close-viewport").click( function() {
|
||||
if ( $("#overview-border").css("right") == "0px" ) {
|
||||
$("#overview-border").css("right", "20000px");
|
||||
$("#close-viewport").css("background-position", "12px 0px");
|
||||
$.jStore.ready(function(engine) {
|
||||
engine.ready(function() {
|
||||
// On load, set the size to the pref stored in local storage if it exists
|
||||
overview_size = $.jStore.store("overview-size");
|
||||
if (overview_size) {
|
||||
$("#overview-border").css( {
|
||||
width: overview_size,
|
||||
height: overview_size
|
||||
});
|
||||
}
|
||||
|
||||
} else {
|
||||
$("#overview-border").css("right", "0px");
|
||||
$("#close-viewport").css("background-position", "0px 0px");
|
||||
}
|
||||
|
||||
// Show viewport on load unless pref says it's off
|
||||
$.jStore.store("overview-off") ? hide_overview() : show_overview()
|
||||
});
|
||||
});
|
||||
|
||||
// Stores the size of the overview into local storage when it's resized
|
||||
$("#overview-border").bind( "dragend", function( e ) {
|
||||
var op = $(this).offsetParent();
|
||||
var opo = op.offset();
|
||||
var new_size = Math.max( op.width() - ( e.offsetX - opo.left ),
|
||||
op.height() - ( e.offsetY - opo.top ) );
|
||||
$.jStore.store("overview-size", new_size + "px");
|
||||
});
|
||||
|
||||
function show_overview() {
|
||||
$.jStore.remove("overview-off");
|
||||
$("#overview-border").css("right", "0px");
|
||||
$("#close-viewport").css("background-position", "0px 0px");
|
||||
}
|
||||
|
||||
function hide_overview() {
|
||||
$.jStore.store("overview-off", true);
|
||||
$("#overview-border").css("right", "20000px");
|
||||
$("#close-viewport").css("background-position", "12px 0px");
|
||||
}
|
||||
|
||||
// Lets the overview be toggled visible and invisible, adjusting the arrows accordingly
|
||||
$("#close-viewport").click( function() {
|
||||
$("#overview-border").css("right") == "0px" ? hide_overview() : show_overview();
|
||||
});
|
||||
|
||||
// Unload handler
|
||||
@@ -245,10 +282,6 @@
|
||||
beforeSubmit: function( data ) {
|
||||
data.push( { name: 'tool_state', value: node.tool_state } );
|
||||
data.push( { name: '_', value: "true" } );
|
||||
$("#tool-form-save-button").each( function() {
|
||||
this.value = "Saving...";
|
||||
this.disabled = true;
|
||||
});
|
||||
}
|
||||
}).each( function() {
|
||||
form = this;
|
||||
@@ -275,6 +308,7 @@
|
||||
|
||||
var close_editor = function() {
|
||||
<% next_url = h.url_for( controller='workflow', action='index' ) %>
|
||||
workflow.check_changes_in_active_form();
|
||||
if ( workflow && workflow.has_changes ) {
|
||||
do_close = function() {
|
||||
window.onbeforeunload = undefined;
|
||||
@@ -297,39 +331,46 @@
|
||||
|
||||
var save_current_workflow = function ( success_callback ) {
|
||||
show_modal( "Saving workflow", "progress" );
|
||||
$.ajax( {
|
||||
url: "${h.url_for( action='save_workflow' )}",
|
||||
type: "POST",
|
||||
data: {
|
||||
id: "${trans.security.encode_id( workflow_id )}",
|
||||
workflow_data: $.toJSON( workflow.to_simple() ),
|
||||
"_": "true"
|
||||
},
|
||||
dataType: 'json',
|
||||
success: function( data ) {
|
||||
var body = $("<div></div>").text( data.message );
|
||||
if ( data.errors ) {
|
||||
body.addClass( "warningmark" )
|
||||
var errlist = $( "<ul/>" );
|
||||
$.each( data.errors, function( i, v ) {
|
||||
$("<li></li>").text( v ).appendTo( errlist );
|
||||
});
|
||||
body.append( errlist );
|
||||
} else {
|
||||
body.addClass( "donemark" );
|
||||
workflow.check_changes_in_active_form();
|
||||
// We bind to ajaxStop because of auto-saving, since the form submission ajax
|
||||
// call needs to be completed so that the new data is saved
|
||||
$(document).bind('ajaxStop.save_workflow', function() {
|
||||
$(document).unbind('ajaxStop.save_workflow');
|
||||
$.ajax( {
|
||||
url: "${h.url_for( action='save_workflow' )}",
|
||||
type: "POST",
|
||||
data: {
|
||||
id: "${trans.security.encode_id( workflow_id )}",
|
||||
workflow_data: function() { return $.toJSON( workflow.to_simple() ) },
|
||||
"_": "true"
|
||||
},
|
||||
dataType: 'json',
|
||||
success: function( data ) {
|
||||
var body = $("<div></div>").text( data.message );
|
||||
if ( data.errors ) {
|
||||
body.addClass( "warningmark" )
|
||||
var errlist = $( "<ul/>" );
|
||||
$.each( data.errors, function( i, v ) {
|
||||
$("<li></li>").text( v ).appendTo( errlist );
|
||||
});
|
||||
body.append( errlist );
|
||||
} else {
|
||||
body.addClass( "donemark" );
|
||||
}
|
||||
workflow.name = data.name;
|
||||
workflow.has_changes = false;
|
||||
workflow.stored = true;
|
||||
if ( success_callback ) {
|
||||
success_callback();
|
||||
}
|
||||
if ( data.errors ) {
|
||||
show_modal( "Saving workflow", body, { "Ok" : hide_modal } );
|
||||
} else {
|
||||
hide_modal();
|
||||
}
|
||||
}
|
||||
workflow.name = data.name;
|
||||
workflow.has_changes = false;
|
||||
workflow.stored = true;
|
||||
if ( success_callback ) {
|
||||
success_callback();
|
||||
}
|
||||
if ( data.errors ) {
|
||||
show_modal( "Saving workflow", body, { "Ok" : hide_modal } );
|
||||
} else {
|
||||
hide_modal();
|
||||
}
|
||||
}
|
||||
});
|
||||
$(document).unbind('ajaxStop.save_workflow'); // IE7 needs it here
|
||||
});
|
||||
}
|
||||
|
||||
@@ -642,7 +683,7 @@
|
||||
<div id="canvas-viewport" style="width: 100%; height: 100%; position: absolute; overflow: hidden; background: #EEEEEE; background: white url(${h.url_for('/static/images/light_gray_grid.gif')}) repeat;">
|
||||
<div id="canvas-container" style="position: absolute; width: 100%; height: 100%;"></div>
|
||||
</div>
|
||||
<div id="overview-border" style="position: absolute; width: 150px; height: 150px; right: 0px; bottom: 0px; border-top: solid gray 1px; border-left: solid grey 1px; padding: 7px 0 0 7px; background: #EEEEEE no-repeat url(${h.url_for('/static/images/resizable.png')}); z-index: 20000; overflow: hidden; max-width: 300px; max-height: 300px; min-width: 50px; min-height: 50px">
|
||||
<div id="overview-border" style="position: absolute; width: 150px; height: 150px; right: 20000px; bottom: 0px; border-top: solid gray 1px; border-left: solid grey 1px; padding: 7px 0 0 7px; background: #EEEEEE no-repeat url(${h.url_for('/static/images/resizable.png')}); z-index: 20000; overflow: hidden; max-width: 300px; max-height: 300px; min-width: 50px; min-height: 50px">
|
||||
<div style="position: relative; overflow: hidden; width: 100%; height: 100%; border-top: solid gray 1px; border-left: solid grey 1px;">
|
||||
<div id="overview" style="position: absolute;">
|
||||
<canvas width="0" height="0" style="background: white; width: 100%; height: 100%;" id="overview-canvas"></canvas>
|
||||
@@ -650,7 +691,7 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="close-viewport" style="border-left: 1px solid #999; border-top: 1px solid #999; background: #ddd url(${h.url_for('/static/images/overview_arrows.png')}); position: absolute; right: 0px; bottom: 0px; width: 12px; height: 12px; z-index: 25000;"></div>
|
||||
<div id="close-viewport" style="border-left: 1px solid #999; border-top: 1px solid #999; background: #ddd url(${h.url_for('/static/images/overview_arrows.png')}) 12px 0px; position: absolute; right: 0px; bottom: 0px; width: 12px; height: 12px; z-index: 25000;"></div>
|
||||
</div>
|
||||
|
||||
</%def>
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
${input.label}:
|
||||
</label>
|
||||
<div style="float: left; width: 250px; margin-right: 10px;">
|
||||
<input type="${input.type}" name="${input.name}" value="${input.value}" size="40">
|
||||
<input type="${input.type}" name="${input.name | h}" value="${input.value | h}" size="30">
|
||||
</div>
|
||||
%if input.error:
|
||||
<div style="float: left; color: red; font-weight: bold; padding-top: 1px; padding-bottom: 3px;">
|
||||
@@ -33,11 +33,14 @@
|
||||
|
||||
</div>
|
||||
%endfor
|
||||
<div class="form-row"><input type="submit" value="${form.submit_text}"></div>
|
||||
%else:
|
||||
<div class="form-row"><i>No options</i></div>
|
||||
%endif
|
||||
</table>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script type="text/javascript">
|
||||
workflow.enable_auto_save();
|
||||
</script>
|
||||
|
||||
@@ -93,7 +93,7 @@ from galaxy.util.expressions import ExpressionContext
|
||||
<div style="clear: both"></div>
|
||||
</div>
|
||||
</%def>
|
||||
|
||||
|
||||
<div class="toolForm">
|
||||
<div class="toolFormTitle">Tool: ${tool.name}</div>
|
||||
<div class="toolFormBody">
|
||||
@@ -105,9 +105,11 @@ from galaxy.util.expressions import ExpressionContext
|
||||
%endif
|
||||
${do_inputs( inputs, values, errors, "" )}
|
||||
%endfor
|
||||
<div class="form-row">
|
||||
<input type="submit" id="tool-form-save-button" value="Save"></input>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script type="text/javascript">
|
||||
workflow.enable_auto_save();
|
||||
</script>
|
||||
|
||||
|
||||
@@ -74,7 +74,7 @@ See Galaxy Interval Operation Screencasts_ (right click to open this link in ano
|
||||
**Syntax**
|
||||
|
||||
- **Maximum distance** is greatest distance in base pairs allowed between intervals that will be considered "clustered". **Negative** values for distance are allowed, and are useful for clustering intervals that overlap.
|
||||
- **Minimum intervals per cluster** allow a threshold to be set on the minimum number of intervals to be considered a cluster. Any area with less than this minimum will not be included in the ouput.
|
||||
- **Minimum intervals per cluster** allow a threshold to be set on the minimum number of intervals to be considered a cluster. Any area with less than this minimum will not be included in the output.
|
||||
- **Merge clusters into single intervals** outputs intervals that span the entire cluster.
|
||||
- **Find cluster intervals; preserve comments and order** filters out non-cluster intervals while maintaining the original ordering and comments in the file.
|
||||
- **Find cluster intervals; output grouped by clusters** filters out non-cluster intervals, but outputs the cluster intervals so that they are grouped together. Comments and original ordering in the file are lost.
|
||||
|
||||
Reference in New Issue
Block a user