[Tynstep-svn] r217 - in trunk/step: step-core/src/main/java/com/tyndalehouse/step/core/service/impl step-core/src/test/java/com/tyndalehouse/step/core/service step-web/src/main/webapp step-web/src/main/webapp/css step-web/src/main/webapp/js step-web/src/main/webapp/libs step-web/src/main/webapp/libs/cookies

ChrisBurrell at crosswire.org ChrisBurrell at crosswire.org
Sun Mar 6 14:00:24 MST 2011


Author: ChrisBurrell
Date: 2011-03-06 14:00:24 -0700 (Sun, 06 Mar 2011)
New Revision: 217

Added:
   trunk/step/step-web/src/main/webapp/libs/cookies/
   trunk/step/step-web/src/main/webapp/libs/cookies/jquery_cookie.js
Removed:
   trunk/step/step-web/src/main/webapp/css/ui-layout/
Modified:
   trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/service/impl/JSwordServiceImpl.java
   trunk/step/step-core/src/test/java/com/tyndalehouse/step/core/service/JSwordServiceImplTest.java
   trunk/step/step-web/src/main/webapp/css/initial-layout.css
   trunk/step/step-web/src/main/webapp/index.jsp
   trunk/step/step-web/src/main/webapp/js/bookmark.js
   trunk/step/step-web/src/main/webapp/js/init.js
   trunk/step/step-web/src/main/webapp/js/passage.js
   trunk/step/step-web/src/main/webapp/js/util.js
Log:
storing state and bookmarks 1st draft

Modified: trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/service/impl/JSwordServiceImpl.java
===================================================================
--- trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/service/impl/JSwordServiceImpl.java	2011-03-01 22:28:39 UTC (rev 216)
+++ trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/service/impl/JSwordServiceImpl.java	2011-03-06 21:00:24 UTC (rev 217)
@@ -1,11 +1,11 @@
 package com.tyndalehouse.step.core.service.impl;
 
-import static com.tyndalehouse.step.core.xsl.XslConversionType.DEFAULT;
 import static org.apache.commons.lang.StringUtils.isBlank;
 import static org.apache.commons.lang.StringUtils.isNotBlank;
 import static org.apache.commons.lang.StringUtils.isNotEmpty;
 import static org.crosswire.jsword.book.BookCategory.BIBLE;
 
+import java.net.URI;
 import java.net.URISyntaxException;
 import java.util.ArrayList;
 import java.util.HashSet;
@@ -113,7 +113,7 @@
     }
 
     @Override
-    public String getOsisText(final String version, final String reference, final List<LookupOption> options,
+    public synchronized String getOsisText(final String version, final String reference, final List<LookupOption> options,
             final String interlinearVersion) {
         LOGGER.debug("Retrieving text for ({}, {})", version, reference);
 
@@ -126,38 +126,37 @@
             }
 
             final BookData bookData = new BookData(currentBook, currentBook.getKey(reference));
-            final Set<XslConversionType> requiredTransformation = identifyStyleSheet(options);
+            final XslConversionType requiredTransformation = identifyStyleSheet(options);
 
             // TODO: This is a workaround while jsword is being fixed. see JS-109, and email from CJB on
             // 27/02/2011
-            synchronized (this) {
-                final SAXEventProvider osissep = bookData.getSAXEventProvider();
-                TransformingSAXEventProvider htmlsep = null;
-                htmlsep = (TransformingSAXEventProvider) new Converter() {
+            // synchronized (this) {
 
-                    public SAXEventProvider convert(final SAXEventProvider provider)
-                            throws TransformerException {
-                        try {
-                            // for now, we just assume that we'll only have one option, but this may change
-                            // later
-                            // TODO, we can probably cache the resource
-                            final TransformingSAXEventProvider tsep = new TransformingSAXEventProvider(
-                                    getClass()
-                                            .getResource(requiredTransformation.iterator().next().getFile())
-                                            .toURI(), osissep);
+            final SAXEventProvider osissep = bookData.getSAXEventProvider();
+            TransformingSAXEventProvider htmlsep = null;
+            htmlsep = (TransformingSAXEventProvider) new Converter() {
+                public SAXEventProvider convert(final SAXEventProvider provider) throws TransformerException {
+                    try {
+                        final String file = requiredTransformation.getFile();
+                        final URI resourceURI = getClass().getResource(file).toURI();
 
-                            // set parameters here
-                            setOptions(tsep, options, version, reference);
-                            setupInterlinearOptions(tsep, interlinearVersion, reference);
-                            return tsep;
-                        } catch (final URISyntaxException e) {
-                            throw new StepInternalException("Failed to load resource correctly", e);
-                        }
-                    }
+                        // for now, we just assume that we'll only have one option, but this may change
+                        // later
 
-                }.convert(osissep);
-                return XMLUtil.writeToString(htmlsep);
-            }
+                        final TransformingSAXEventProvider tsep = new TransformingSAXEventProvider(
+                                resourceURI, osissep);
+
+                        // set parameters here
+                        setOptions(tsep, options, version, reference);
+                        setupInterlinearOptions(tsep, interlinearVersion, reference);
+                        return tsep;
+                    } catch (final URISyntaxException e) {
+                        throw new StepInternalException("Failed to load resource correctly", e);
+                    }
+                }
+            }.convert(osissep);
+            return XMLUtil.writeToString(htmlsep);
+            // }
         } catch (final NoSuchKeyException e) {
             throw new StepInternalException("The verse specified was not found: " + reference, e);
         } catch (final BookException e) {
@@ -171,26 +170,24 @@
     }
 
     /**
-     * returns the stylesheet that should be used to generate the text
+     * At the moment, we only support one stylesheet at the moment, so we only need to return one This may
+     * change, but at that point we'll have a cleared view on requirements. For now, if one of the options
+     * triggers anything but the default, then we return that. returns the stylesheet that should be used to
+     * generate the text
      * 
      * @param options the list of options that are currently applied to the passage
      * @return the stylesheet (of stylesheets)
      */
-    private Set<XslConversionType> identifyStyleSheet(final List<LookupOption> options) {
+    private XslConversionType identifyStyleSheet(final List<LookupOption> options) {
         final Set<XslConversionType> chosenOptions = new HashSet<XslConversionType>();
 
         for (final LookupOption lo : options) {
-            chosenOptions.add(lo.getStylesheet());
+            if (!XslConversionType.DEFAULT.equals(lo.getStylesheet())) {
+                return lo.getStylesheet();
+            }
         }
 
-        // remove from the list any default:
-        if (chosenOptions.contains(DEFAULT) && chosenOptions.size() > 1) {
-            chosenOptions.remove(DEFAULT);
-        } else if (chosenOptions.isEmpty()) {
-            chosenOptions.add(DEFAULT);
-        }
-
-        return chosenOptions;
+        return XslConversionType.DEFAULT;
     }
 
     @Override

Modified: trunk/step/step-core/src/test/java/com/tyndalehouse/step/core/service/JSwordServiceImplTest.java
===================================================================
--- trunk/step/step-core/src/test/java/com/tyndalehouse/step/core/service/JSwordServiceImplTest.java	2011-03-01 22:28:39 UTC (rev 216)
+++ trunk/step/step-core/src/test/java/com/tyndalehouse/step/core/service/JSwordServiceImplTest.java	2011-03-06 21:00:24 UTC (rev 217)
@@ -97,4 +97,63 @@
         LOGGER.debug("\n {}", xmlOutputter.outputString(d));
         Assert.assertTrue(osisText.contains("span"));
     }
+
+    /**
+     * tries to replicate the issue with bookdata not being able to be read in a concurrent fashion
+     * 
+     * @throws NoSuchKeyException a no such key exception
+     * @throws BookException a book exception
+     * @throws InterruptedException when the thread is interrupted
+     */
+    @Test
+    public void testConcurrencyIssueOnBookData() throws NoSuchKeyException, BookException,
+            InterruptedException {
+        final String[] names = { "KJV", "ESV" };
+        final String ref = "Rom.1.1";
+
+        final Runnable r1 = new Runnable() {
+            @Override
+            public void run() {
+                final Book b0 = Books.installed().getBook(names[0]);
+                BookData bd1;
+                try {
+                    bd1 = new BookData(b0, b0.getKey(ref));
+                    bd1.getSAXEventProvider();
+                } catch (final NoSuchKeyException e) {
+                    e.printStackTrace();
+                } catch (final BookException e) {
+                    e.printStackTrace();
+                }
+
+            }
+        };
+
+        final Runnable r2 = new Runnable() {
+            @Override
+            public void run() {
+                final Book b0 = Books.installed().getBook(names[1]);
+                BookData bd1;
+                try {
+                    bd1 = new BookData(b0, b0.getKey(ref));
+                    bd1.getSAXEventProvider();
+                } catch (final NoSuchKeyException e) {
+                    e.printStackTrace();
+                } catch (final BookException e) {
+                    e.printStackTrace();
+                }
+
+            }
+        };
+
+        int ii = 0;
+        while (ii++ < 1000) {
+            final Thread t1 = new Thread(r1);
+            final Thread t2 = new Thread(r2);
+            t1.start();
+            t2.start();
+
+            t1.join();
+            t2.join();
+        }
+    }
 }

Modified: trunk/step/step-web/src/main/webapp/css/initial-layout.css
===================================================================
--- trunk/step/step-web/src/main/webapp/css/initial-layout.css	2011-03-01 22:28:39 UTC (rev 216)
+++ trunk/step/step-web/src/main/webapp/css/initial-layout.css	2011-03-06 21:00:24 UTC (rev 217)
@@ -71,13 +71,25 @@
 	height: 56px;
 } 
 
-.bookmarksContent {
+.bookmarkPane {
 	margin: 0px 5px;
 	border: 1px solid #cccc99;
 	text-align: center;
 }
 
+.bookmarkItem {
+	clear: both;
+	display: block;	
+}
 
+.leftBookmarkArrow {
+	float: left;
+}
+
+.rightBookmarkArrow {
+	float: right;
+}
+
 /**************************/
 /* TOP MENU
 /**************************/
@@ -111,7 +123,7 @@
 	margin-left: -1px; 
 }
 
-.bookmarksContent {
+.bookmarkPane {
 	background: #EEF;
 }
 

Modified: trunk/step/step-web/src/main/webapp/index.jsp
===================================================================
--- trunk/step/step-web/src/main/webapp/index.jsp	2011-03-01 22:28:39 UTC (rev 216)
+++ trunk/step/step-web/src/main/webapp/index.jsp	2011-03-06 21:00:24 UTC (rev 217)
@@ -5,7 +5,6 @@
     <META http-equiv="Content-Type" content="text/html; charset=utf-8">
     <TITLE>STEP :: Scripture Tools for Every Pastor</TITLE>
 
-    <link rel="stylesheet" type="text/css" href="css/ui-layout/layout-default.css" />
     <link rel="stylesheet" type="text/css" href="css/ui-lightness/jquery-ui-1.8.5.custom.css" />
     <link rel="stylesheet" type="text/css" href="css/initial-layout.css" />
     <link rel="stylesheet" type="text/css" href="css/initial-fonts.css" />
@@ -20,6 +19,7 @@
     <script src="libs/jquery-ui-1.8.5.custom.min.js" type="text/javascript"></script>
     <script src="libs/jquery-shout.js" type="text/javascript"></script>
 	<script src="libs/menu/ddsmoothmenu.js" type="text/javascript"></script>
+    <script src="libs/cookies/jquery_cookie.js" type="text/javascript"></script>
     
     <script src="js/util.js" type="text/javascript"></script>
     <script src="js/passage.js" type="text/javascript"></script>
@@ -49,12 +49,15 @@
 	</div>
 </div>
 	
-<div class="ui-layout-center bookmarks" id="bookmarkPane">
-	<div class="ui-layout-north northBookmark">
+<div class="bookmarks" id="centerPane">
+	<div class="northBookmark">
 		<img id="topLogo" src="images/step-logo.png" alt="STEP :: Scripture Tools for Every Pastor" />
 	</div>
-	<div id="bookmarkPane" class="ui-layout-center bookmarksContent"><span>Bookmarks</span></div>
-	<div class="ui-layout-south logo">
+	<div class="bookmarkPane">
+		<span>History<br /><br /></span>
+		<span class="bookmarkContents"></span>
+	</div>
+	<div class="logo">
 		<span class="copyright">© Tyndale House</span>
 	</div>
 </div>
@@ -65,7 +68,7 @@
 		<div id="rightPaneMenu" class="innerMenus"></div>
 	    <div class="passageText ui-widget">
 	    	<div class="headingContainer">
-		    	<input id="leftPassageReference" class="heading editable passageReference" size="30" value="Jhn 1:1;1 Jhn 1:1" />
+		    	<input id="leftPassageReference" class="heading editable passageReference" size="30" value="Jhn 1:1" />
 		    	<input id="leftPassageBook" class="heading editable passageVersion" size="5" value="ESV" />
 	    	</div>
 	    	<div class="passageContent"></div>

Modified: trunk/step/step-web/src/main/webapp/js/bookmark.js
===================================================================
--- trunk/step/step-web/src/main/webapp/js/bookmark.js	2011-03-01 22:28:39 UTC (rev 216)
+++ trunk/step/step-web/src/main/webapp/js/bookmark.js	2011-03-06 21:00:24 UTC (rev 217)
@@ -9,66 +9,85 @@
 	
 	//listen to passage changes
 	this.bookmarkContainer.hear("passage-changed", function(selfElement, data) {
-		self.addHistory(data);
+		self.addHistory(data.reference);
 	});
+	
+	this.initialiseHistory();
 }
 
+Bookmark.maxBookmarks = 10;
+Bookmark.historyDelimiter = '#';
 
+//we need to ignore the first two passage changes since we have those in the history
+//the history giving us the order of things
+Bookmark.ignoreChangePassage = 2;
+
 /**
  * Adding a bookmark
  */
 Bookmark.prototype.addHistory = function(passageReference) {
-	//construct bookmark
-//	var item = "<span>" + passageReference + "</span>";
-//	$("#bookmarkPane span").prepend(item);
-}	
+	//we ignore the first two items:
+	if(Bookmark.ignoreChangePassage != 0) {
+		Bookmark.ignoreChangePassage--;
+		return;
+	}
 	
 	
+	//if we have the bookmark already, then we stop here
+	var history = this.getHistory();
 	
+	var indexInHistory = $.inArray(passageReference, history);
 	
-	//	var bookmark = this.get(passageReference);
-//	if(bookmark) {
-//		//move bookmark around
-//		
-//		return;
-//	}
-//	
-//	//otherwise we create the bookmark
-//	bookmark = "<span class='bookmark'>" +
-//			"<a href='#left-" + passageReference + "' >" + "left-arrow" +"</a>" +
-//			passageReference +
-//			"<a href='#right-" + passageReference + "' >" + "right-arrow" +"</a>" +;
-//	
-//	$(this.bookmarkContainer).append(bookmark);
-//	
-//	//insert bookmark here => i.e. it would be good to have a linked list implementation? (or perhaps, 
-//	//we insert whatever...
-//	this.currentBookmarks.insert(bookmark);
-//}
-//
-///**
-// * gets a bookmark
-// */
-//Bookmark.prototype.get = function(passageReference) {
-//	//TODO check this
-//	return $("val() = " + passageReference, this.bookmarkContainer);
-////or
-//	/*
-//	var i = 0;
-//	for(i = 0; i < this.currentBookmarks.length; i++) {
-//		if(this.currentBookmarks[i].val() = passageReference) {
-//			return this.currentBookmarks[i];
-//		}
-//	}*/
-//}
-//
-///** 
-// * removes a bookmark from the list
-// */
-//Bookmark.prototype.remove(reference) {
-//	var b = getBookmark(reference);
-//	if(b) {
-//		b.removeFromParent();
-//	}
-//}
+	if(indexInHistory == -1) {
+		if(history.length > Bookmark.maxBookmarks) {
+			//we remove the first element in the array (i.e. the last child).
+			history.pop();
+			$("div.bookmarkItem:last", this.bookmarkContainer).remove();
+		}
+		
+		//then add
+		this.createBookmarkItem(passageReference);
+		history.unshift(passageReference);
+	} else {
+		//reposition item...
+		var item = $("div.bookmarkItem", this.bookmarkContainer).eq(indexInHistory).detach();
+		history.splice(indexInHistory, 1);
+		this.bookmarkContainer.prepend(item);
+		history.unshift(passageReference);
+	}
+	
+	this.setHistory(history);
+};	
+	
+Bookmark.prototype.initialiseHistory = function() {
+	var history = this.getHistory();
+	if(history != null) {
+		for(var ii = history.length -1; ii >= 0; ii--) {
+			this.createBookmarkItem(history[ii]);
+		}
+	}
+}
 
+Bookmark.prototype.createBookmarkItem = function(passageReference) {
+	if(passageReference && passageReference != "") {
+		var item = "<div class='bookmarkItem'>";
+		item += "<a class='ui-icon ui-icon-arrowthick-1-w bookmarkArrow leftBookmarkArrow' href='#' onclick='$.shout(\"bookmark-triggered-0\", \""+ passageReference + "\");'>←</a>";
+		item += passageReference;
+		item += "<a class='ui-icon ui-icon-arrowthick-1-e bookmarkArrow rightBookmarkArrow' href='#' onclick='$.shout(\"bookmark-triggered-1\", \""+ passageReference + "\");'>→</a>";
+		item += "</div>";
+		
+		this.bookmarkContainer.prepend(item);
+	}
+};
+
+Bookmark.prototype.getHistory = function() {
+	var history = $.cookie("history");
+	if(history == null) {
+		return [];
+	}
+	return history.split(Bookmark.historyDelimiter);
+};
+
+Bookmark.prototype.setHistory = function(history) {
+	$.cookie("history", history.join(Bookmark.historyDelimiter))
+};

Modified: trunk/step/step-web/src/main/webapp/js/init.js
===================================================================
--- trunk/step/step-web/src/main/webapp/js/init.js	2011-03-01 22:28:39 UTC (rev 216)
+++ trunk/step/step-web/src/main/webapp/js/init.js	2011-03-06 21:00:24 UTC (rev 217)
@@ -31,7 +31,7 @@
 		var topMenuHeight = $("#topMenu").height();
 		var imageAndFooterHeight = $(".northBookmark").height() + $(".logo").height();
 		$(".column").height(windowHeight - topMenuHeight);
-		$(".bookmarksContent").height(windowHeight - topMenuHeight - imageAndFooterHeight);
+		$(".bookmarkPane").height(windowHeight - topMenuHeight - imageAndFooterHeight);
 	});
 	
 	//listen to layout changes and alert
@@ -94,6 +94,7 @@
 
 
 function initData() {
+	
 	//get all supported versions
 	var options;
 	$.getJSON(BIBLE_GET_ALL_FEATURES, function(data) {
@@ -179,9 +180,6 @@
 		function() {
 			return !($(".passageContainer[passage-id = '0'] .passageVersion") === undefined
 			    || $(".passageContainer[passage-id = '1'] .passageVersion").val() === undefined);
-			
-//			return !($._jq_shout.registry["version-changed-0"] === undefined
-//		 		|| $._jq_shout.registry["version-changed-1"] === undefined);
 	}, 	function() {
 			$.shout("version-changed-" + 0, $(".passageContainer[passage-id = '0'] .passageVersion").val());
 			$.shout("version-changed-" + 1, $(".passageContainer[passage-id = '1'] .passageVersion").val());
@@ -222,7 +220,7 @@
 }
 
 function initBookmarks() {
-	new Bookmark($("#bookmarkPane"));
+	new Bookmark($(".bookmarkContents"));
 }
 
 function initTimeline(mainAppLayout) {

Modified: trunk/step/step-web/src/main/webapp/js/passage.js
===================================================================
--- trunk/step/step-web/src/main/webapp/js/passage.js	2011-03-01 22:28:39 UTC (rev 216)
+++ trunk/step/step-web/src/main/webapp/js/passage.js	2011-03-06 21:00:24 UTC (rev 217)
@@ -13,6 +13,9 @@
 	this.passage = $(".passageContent", passageContainer);
 	this.passageId = passageId;
 	
+	//read state from the cookie
+	this.setInitialPassage();
+	
 	// set up autocomplete
 	this.version.autocomplete({
 		source : versions,
@@ -22,9 +25,6 @@
 			$(this).val(ui.item.value);
 			$(this).change();
 		},
-		change: function() {
-//			$.shout("version-change-" + this.passageId);
-		}
 	}).focus(function() {
 		self.version.autocomplete("search", "");
 	}).change(function() {
@@ -46,9 +46,31 @@
 		//we only care about this event if the menu was within the container...
 		self.changePassage();
 	});
+	
+
+	//register when we want to be alerted that a bookmark has changed
+	this.passage.hear("bookmark-triggered-" + this.passageId, function(selfElement, data) {
+		self.reference.val(data);
+		self.changePassage();
+	});
 }
 
 /**
+ * sets up the initial passages based on the cookie state
+ */
+Passage.prototype.setInitialPassage = function() {
+	var cookieReference = $.cookie("currentReference-" + this.passageId);
+	var cookieVersion = $.cookie("currentVersion-" + this.passageId);
+	if(cookieReference != null) {
+		this.reference.val(cookieReference);
+	}
+	
+	if(cookieVersion != null) {
+		this.version.val(cookieVersion);
+	}
+}
+
+/**
  * changes the passage, with optional parameters
  */
 Passage.prototype.changePassage = function() {
@@ -67,9 +89,9 @@
 	
 	if(lookupReference && lookupVersion 
 			&& lookupVersion != "" && lookupReference != ""
-			&& (   lookupVersion != this.currentVersion 
-				|| lookupReference != this.currentReference
-			    || interlinearVersion != this.currentInterlinearVersion
+			&& (   lookupVersion != $.cookie("currentVersion-" + this.passageId) 
+				|| lookupReference != $.cookie("currentReference-" + this.passageId)
+			    || interlinearVersion != $.cookie("currentInterlinearVersion-" + this.passageId)
 				|| !compare(options, this.currentOptions)) 
 		) {
 		var url = BIBLE_GET_BIBLE_TEXT + lookupVersion + "/" + lookupReference;
@@ -85,14 +107,17 @@
 		//send to server
 		$.get(url, function (text) {
 			//we get html back, so we insert into passage:
-			self.currentReference = lookupReference;
-			self.currentVersion = lookupVersion;
+			$.cookie("currentReference-" + self.passageId, lookupReference);
+			$.cookie("currentVersion-" + self.passageId, lookupVersion);
+			$.cookie("currentOptions-" + self.passageId, options);
+			$.cookie("currentInterlinearVersion-" + self.passageId, interlinearVersion);
+
+			//TODO remove completely in favour of cookie storage only
 			self.currentOptions = options;
-			self.currentInterlinearVersion = interlinearVersion;
 			self.passage.html(text.value);
 			
 			//passage change was successful, so we let the rest of the UI know
-			$.shout("passage-changed", self.reference.val());
+			$.shout("passage-changed", { reference: self.reference.val(), passageId: self.passageId, init: init } );
 		});
 	}
 }

Modified: trunk/step/step-web/src/main/webapp/js/util.js
===================================================================
--- trunk/step/step-web/src/main/webapp/js/util.js	2011-03-01 22:28:39 UTC (rev 216)
+++ trunk/step/step-web/src/main/webapp/js/util.js	2011-03-06 21:00:24 UTC (rev 217)
@@ -3,6 +3,10 @@
  * extending jquery to have array comparison
  */
 function compare(s, t) {
+	if(s == null || t == null) {
+		return t == s;
+	}
+	
     if (s.length != t.length) { return false; }
     var a = s.sort(),
         b = t.sort();

Added: trunk/step/step-web/src/main/webapp/libs/cookies/jquery_cookie.js
===================================================================
--- trunk/step/step-web/src/main/webapp/libs/cookies/jquery_cookie.js	                        (rev 0)
+++ trunk/step/step-web/src/main/webapp/libs/cookies/jquery_cookie.js	2011-03-06 21:00:24 UTC (rev 217)
@@ -0,0 +1,96 @@
+/**
+ * Cookie plugin
+ *
+ * Copyright (c) 2006 Klaus Hartl (stilbuero.de)
+ * Dual licensed under the MIT and GPL licenses:
+ * http://www.opensource.org/licenses/mit-license.php
+ * http://www.gnu.org/licenses/gpl.html
+ *
+ */
+
+/**
+ * Create a cookie with the given name and value and other optional parameters.
+ *
+ * @example $.cookie('the_cookie', 'the_value');
+ * @desc Set the value of a cookie.
+ * @example $.cookie('the_cookie', 'the_value', { expires: 7, path: '/', domain: 'jquery.com', secure: true });
+ * @desc Create a cookie with all available options.
+ * @example $.cookie('the_cookie', 'the_value');
+ * @desc Create a session cookie.
+ * @example $.cookie('the_cookie', null);
+ * @desc Delete a cookie by passing null as value. Keep in mind that you have to use the same path and domain
+ *       used when the cookie was set.
+ *
+ * @param String name The name of the cookie.
+ * @param String value The value of the cookie.
+ * @param Object options An object literal containing key/value pairs to provide optional cookie attributes.
+ * @option Number|Date expires Either an integer specifying the expiration date from now on in days or a Date object.
+ *                             If a negative value is specified (e.g. a date in the past), the cookie will be deleted.
+ *                             If set to null or omitted, the cookie will be a session cookie and will not be retained
+ *                             when the the browser exits.
+ * @option String path The value of the path atribute of the cookie (default: path of page that created the cookie).
+ * @option String domain The value of the domain attribute of the cookie (default: domain of page that created the cookie).
+ * @option Boolean secure If true, the secure attribute of the cookie will be set and the cookie transmission will
+ *                        require a secure protocol (like HTTPS).
+ * @type undefined
+ *
+ * @name $.cookie
+ * @cat Plugins/Cookie
+ * @author Klaus Hartl/klaus.hartl at stilbuero.de
+ */
+
+/**
+ * Get the value of a cookie with the given name.
+ *
+ * @example $.cookie('the_cookie');
+ * @desc Get the value of a cookie.
+ *
+ * @param String name The name of the cookie.
+ * @return The value of the cookie.
+ * @type String
+ *
+ * @name $.cookie
+ * @cat Plugins/Cookie
+ * @author Klaus Hartl/klaus.hartl at stilbuero.de
+ */
+jQuery.cookie = function(name, value, options) {
+    if (typeof value != 'undefined') { // name and value given, set cookie
+        options = options || {};
+        if (value === null) {
+            value = '';
+            options.expires = -1;
+        }
+        var expires = '';
+        if (options.expires && (typeof options.expires == 'number' || options.expires.toUTCString)) {
+            var date;
+            if (typeof options.expires == 'number') {
+                date = new Date();
+                date.setTime(date.getTime() + (options.expires * 24 * 60 * 60 * 1000));
+            } else {
+                date = options.expires;
+            }
+            expires = '; expires=' + date.toUTCString(); // use expires attribute, max-age is not supported by IE
+        }
+        // CAUTION: Needed to parenthesize options.path and options.domain
+        // in the following expressions, otherwise they evaluate to undefined
+        // in the packed version for some reason...
+        var path = options.path ? '; path=' + (options.path) : '';
+        var domain = options.domain ? '; domain=' + (options.domain) : '';
+        var secure = options.secure ? '; secure' : '';
+        document.cookie = [name, '=', encodeURIComponent(value), expires, path, domain, secure].join('');
+    } else { // only name given, get cookie
+        var cookieValue = null;
+        if (document.cookie && document.cookie != '') {
+            var cookies = document.cookie.split(';');
+            for (var i = 0; i < cookies.length; i++) {
+                var cookie = jQuery.trim(cookies[i]);
+                // Does this cookie string begin with the name we want?
+                if (cookie.substring(0, name.length + 1) == (name + '=')) {
+                    cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
+                    break;
+                }
+            }
+        }
+        return cookieValue;
+    }
+};
\ No newline at end of file


Property changes on: trunk/step/step-web/src/main/webapp/libs/cookies/jquery_cookie.js
___________________________________________________________________
Added: svn:mime-type
   + text/plain




More information about the Tynstep-svn mailing list