<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>False Positives &#187; Web</title>
	<atom:link href="http://www.falsepositives.com/index.php/categorias/code/web/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.falsepositives.com</link>
	<description>Ian Irving&#039;s Code and Culture from Toronto</description>
	<lastBuildDate>Wed, 28 Jul 2010 18:10:27 +0000</lastBuildDate>
	
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<cloud domain='www.falsepositives.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
		<item>
		<title>Quick links as of June 4th 2010</title>
		<link>http://www.falsepositives.com/index.php/2010/06/04/quick-links-as-of-june-4th-2010/</link>
		<comments>http://www.falsepositives.com/index.php/2010/06/04/quick-links-as-of-june-4th-2010/#comments</comments>
		<pubDate>Fri, 04 Jun 2010 14:14:52 +0000</pubDate>
		<dc:creator>Ian</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[GreaseMonkey]]></category>
		<category><![CDATA[Startup]]></category>
		<category><![CDATA[Web]]></category>

		<guid isPermaLink="false">http://www.falsepositives.com/?p=2620</guid>
		<description><![CDATA[
May 28
Jeffery To&#8217;s Show Short Link GreaseMonkey Script displays an existing short link for the current page (in the bottom left corner of the window), taking advantage of the short link microFormat. Flickr, YouTube, TechCrunch and all WordPress blogs already use the rel=&#8221;shortlink&#8221; mircoFormat.  Nice!


Clarify Your Story Excerpt is a set of questions will [...]]]></description>
			<content:encoded><![CDATA[<ul>
<li><em>May 28</em><br />
Jeffery To&#8217;s <a href="http://userscripts.org/scripts/show/77795">Show Short Link GreaseMonkey Script</a> displays an existing short link for the current page (in the bottom left corner of the window), taking advantage of the <a href="http://microformats.org/wiki/rel-shortlink">short link microFormat</a>. Flickr, YouTube, TechCrunch and all WordPress blogs already use the rel=&#8221;shortlink&#8221; mircoFormat.  Nice!
</li>
<li>
<a href="http://www.sramanamitra.com/clarify-your-story-excerpt/">Clarify Your Story Excerpt</a> is a set of questions will help you through the process of testing and validating your idea.  Aimed at &#8220;Enterprise and Small / Medium Facing Businesses (EME)&#8221; they are equal valuable as a questions for any startup.
</li>
<li><em>May 31</em><br />
Mathew Ingram does a great job puncturing gasbag Nick Carr in <a href="http://www.mathewingram.com/work/2010/05/31/nick-carrs-retreat-from-the-internet-continues/">Nick Carr’s Retreat From the Internet Continues</a>.  </p>
<p><a href="http://en.wikipedia.org/wiki/Nicholas_G._Carr">Mr Carr</a> likes to make big (big) contrary positions and watch as people read and buy his work.  He does a service in setting up (some of) these debates, but they rarely seem to hold up.  </p>
<p>Nick Carr’s <a href="http://www.roughtype.com/archives/2010/05/experiments_in.php">argues</a> that links (aka HyperLinks, aka &#8220;the web&#8221;) are bad because readers might click on them and get distracted from the quality of the writing or argument. This looks like the 2010 version of Plato saying &#8220;Writing is bad because it causes people not to rely on memory but to rely on something external to them and depend on signs belonging to another.&#8221; (<a href="http://en.wikipedia.org/wiki/Phaedrus_%28dialogue%29">Phaedrus</a>).  </p>
<p>This de-values the reader by not connecting them to the referred content, and de-values the writing in assuming the quality of the writing can not hold them or that the content (the argument) cannot stand up, either to the referred content, or to comments.  Maybe in a age of finite page size and dead (fixed media), but this goes against the nature and the technology of the web.  It also does not trust the reader.  In this age, link to the primary sources, the raw data and to the debate.  How to link may be a interesting question.  But not linking is to show lack of trust and respect to your audience and to suggest you have something to hide.  </p>
<p>See also The Economist&#8217;s Tech Blogger Babbage in <a href="http://www.economist.com/blogs/babbage/2010/06/pros_and_cons_hyperlinks">To link, or not to link? That is the question.</a></li>
<li>
An interesting, and non trival test of <a href="http://fightingforalostcause.net/misc/2006/compare-email-regex.php">Comparing E-mail Address Validating Regular Expressions</a> using PHP&#8217;s ereg() and preg_match() function finds a winner (where it&#8217;s better to accept a few invalid addresses than reject any valid ones) :</p>
<p>/^([\w\!\#$\%\&#038;\'\*\+\-\/\=\?\^\`{\|\}\~]+\.)*[\w\!\#$\%\&#038;\'\*\+\-\/\=\?\^\`{\|\}\~]+@((((([a-z0-9]{1}[a-z0-9\-]{0,62}[a-z0-9]{1})|[a-z])\.)+[a-z]{2,6})|(\d{1,3}\.){3}\d{1,3}(\:\d{1,5})?)$/i</p>
<p>I wonder if these results in torturing regexp email address recognizers will hold up given the <a href="http://en.wikipedia.org/wiki/Comparison_of_regular_expression_engines">variations in regular_expression engines</a>?
</li>
<li><em>June 2</em><br />
<a href="http://www.readwriteweb.com/archives/twitter_exposes_intersections_in_the_social_graph.php">Twitter Exposes Intersections in the Social Graph</a> like my Greasemonkey Follow Rank script <a title="was http://bit.ly/FollowRank" href="http://userscripts.org/scripts/show/64286" class="tweet-url web" rel="nofollow" target="_blank">http://userscripts.org/scripts/show/64286</a>.
</li>
<li><em>June 3rd</em><br />
 via <a href="http://twitter.com/geoffreywiseman/status/15329473786">Geoffrey Wiseman</a>, Git support in Eclipse getting stronger with the release of <a href="http://aniszczyk.org/2010/06/02/egit-and-jgit-0-8-1-released/">EGit and JGit 0.8.1</a>
</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.falsepositives.com/index.php/2010/06/04/quick-links-as-of-june-4th-2010/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Building a Cascading Drop Down Selection List for Ruby on Rails with jQuery Ajax</title>
		<link>http://www.falsepositives.com/index.php/2010/05/28/building-a-casscading-drop-down-selection-list-for-ruby-on-rails-with-jquery-ajax/</link>
		<comments>http://www.falsepositives.com/index.php/2010/05/28/building-a-casscading-drop-down-selection-list-for-ruby-on-rails-with-jquery-ajax/#comments</comments>
		<pubDate>Fri, 28 May 2010 16:07:20 +0000</pubDate>
		<dc:creator>Ian</dc:creator>
				<category><![CDATA[Ajax]]></category>
		<category><![CDATA[Code]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Ruby and Rails]]></category>

		<guid isPermaLink="false">http://www.falsepositives.com/?p=2594</guid>
		<description><![CDATA[A frequent need in building web site application is to have users select one value and then, based on that value, select another value.  Real world needs for related values might be : Select a Country and then State or Province; Select a Car Manufacture and then a Car Model.  Generically it&#8217;s about [...]]]></description>
			<content:encoded><![CDATA[<p>A frequent need in building web site application is to have users select one value and then, based on that value, select another value.  Real world needs for related values might be : Select a Country and then State or Province; Select a Car Manufacture and then a Car Model.  Generically it&#8217;s about selecting some Category or Section and then selecting the Sub Category or sub Section, the selection of one field cascades the results in another related field.</p>
<p>Also called Related Drop Down fields or Dependant Drop Down lists or Dynamic Drop Downs or Dependent Drop Downs.</p>
<p>What you want to have happen is something that will look and act like this<br />
If you select Veg&#8217;s<br />
<img src="http://www.falsepositives.com/wp-content/uploads/2010/05/RORCDDWA_1.jpg" alt="Select Veg" title="RORCDDWA_1" width="159" height="163" class="alignnone size-full wp-image-2604" /><br />
and then if you select Meat :<br />
<img src="http://www.falsepositives.com/wp-content/uploads/2010/05/RORCDDWA_2.jpg" alt="select beef" title="select beef" width="131" height="170" class="alignnone size-full wp-image-2606" /></p>
<p>Also, in the underlying html select tag code, you want values stored and names displayed so you can a)change or correct the names, b) display the names in a different languages but keep the underlying key values.</p>
<p>In the bad old days you might have them select the first value and the go to a new page for the related values, or at best refresh the entire page.  Thankfully this is the days of shinny and we haz ajax!!   But we still need to get the ducks lined up and quacking in order for this to work.  This is my code to do that.</p>
<p>Note that this solution has been tested with RoR 2.3.5 and jQuery 1.4.2 (standard flavours as of early 2010)</p>
<p>you need to have jQuery loaded on the page and the easest way (althought not always the best way) is to pull all the script for m the public/javascrip direcroty of your application with :</p>
<div class="codecolorer-container javascript default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br /></div></td><td><div class="javascript codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #339933;">&lt;</span> <span style="color: #339933;">%=</span> javascript_include_tag <span style="color: #339933;">:</span>defaults <span style="color: #339933;">%&gt;</span></div></td></tr></tbody></table></div>
<p>in the sample I assuming a Section field and a dependent Sub-Section field.  From a data model perspective the Section mode has a Id and a Name and  has_one :sub_section; and the SubSection has a Id, a Name and a Section Id and  belongs_to :section</p>
<p>in the sub_sections controller</p>
<div class="codecolorer-container ruby default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br /></div></td><td><div class="ruby codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&nbsp; &nbsp; <span style="color:#9966CC; font-weight:bold;">def</span> for_sectionid<br />
&nbsp; &nbsp; &nbsp; <span style="color:#0066ff; font-weight:bold;">@subsections</span> = SubSection.<span style="color:#9900CC;">find</span><span style="color:#006600; font-weight:bold;">&#40;</span> <span style="color:#ff3333; font-weight:bold;">:all</span>, <span style="color:#ff3333; font-weight:bold;">:conditions</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">&quot; section_id = ?&quot;</span>, params<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:id</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#93;</span> &nbsp;<span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">sort_by</span><span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#006600; font-weight:bold;">|</span>k<span style="color:#006600; font-weight:bold;">|</span> k<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'name'</span><span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#006600; font-weight:bold;">&#125;</span> &nbsp; &nbsp;<br />
&nbsp; &nbsp; &nbsp; respond_to <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>format<span style="color:#006600; font-weight:bold;">|</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#CC0066; font-weight:bold;">format</span>.<span style="color:#9900CC;">json</span> &nbsp;<span style="color:#006600; font-weight:bold;">&#123;</span> render <span style="color:#ff3333; font-weight:bold;">:json</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#0066ff; font-weight:bold;">@subsections</span> <span style="color:#006600; font-weight:bold;">&#125;</span> &nbsp; &nbsp; &nbsp;<br />
&nbsp; &nbsp; &nbsp; <span style="color:#9966CC; font-weight:bold;">end</span><br />
&nbsp; &nbsp; &nbsp;<span style="color:#9966CC; font-weight:bold;">end</span></div></td></tr></tbody></table></div>
<p>this is a pretty straight forward piece of code that uses an id passed in the parameters, returns all the subsection objects for that section_id, sorts that collection of subsections by the subsection.name, and renders that collection as a json object.  </p>
<p>As per the notes on the rails wiki for <a href="http://wiki.rubyonrails.org/howtos/security/sql_injection">SQL Injection</a>, you need to sanitize the variables being passed as a parameter, and Ruby on Rails has a built in filter for special SQL characters which you need to apply, as above. :conditions => [" section_id = ?", params[:id]] </p>
<p>Note, you could also use a Dynamic attribute-based finders to get the subsection object :</p>
<div class="codecolorer-container ruby default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br /></div></td><td><div class="ruby codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&nbsp;<span style="color:#0066ff; font-weight:bold;">@subsection</span> = SubSection.<span style="color:#9900CC;">find_all_by_section_id</span><span style="color:#006600; font-weight:bold;">&#40;</span> params<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:id</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">sort_by</span><span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#006600; font-weight:bold;">|</span>k<span style="color:#006600; font-weight:bold;">|</span> k<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'name'</span><span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#006600; font-weight:bold;">&#125;</span></div></td></tr></tbody></table></div>
<p>which is shorter code (less change of a syntax error?) and, as a bonus, automatically applies the sanitize countermeasure. </p>
<p>Further, you might want to create a custom json view for this routine with, only the sub section name and sub section id, if you a) have values want to keep private, or b) the SubSection objection has a lot of data (since we are only interested in 2 fields).  That&#8217;s the reason its in the SubSections Controller, to keep related stuff together.</p>
<p>in the new or edit view for (in this case) gallery</p>
<div class="codecolorer-container html4strict default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br /></div></td><td><div class="html4strict codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #009900;">&lt; % form_for<span style="color: #66cc66;">&#40;</span>@gallery<span style="color: #66cc66;">&#41;</span> do |f| %&gt;</span><br />
...<br />
&nbsp; <span style="color: #009900;">&lt;<a href="http://december.com/html/4/element/p.html"><span style="color: #000000; font-weight: bold;">p</span></a>&gt;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&lt; %<span style="color: #66cc66;">=</span> f.<span style="color: #000066;">label</span> :section_id %&gt;&lt;<a href="http://december.com/html/4/element/br.html"><span style="color: #000000; font-weight: bold;">br</span></a> <span style="color: #66cc66;">/</span>&gt;</span> &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; <span style="color: #009900;">&lt; %<span style="color: #66cc66;">=</span> &nbsp;collection_select<span style="color: #66cc66;">&#40;</span>:gallery, :section_id, Section.all, :<span style="color: #000066;">id</span>, :<span style="color: #000066;">name</span> , options <span style="color: #66cc66;">=</span><span style="color: #66cc66;">&#123;</span>:<span style="color: #000066;">prompt</span> <span style="color: #66cc66;">=</span>&gt;</span> &quot;&quot;} ) %&gt;<br />
&nbsp; &nbsp; <span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><a href="http://december.com/html/4/element/p.html"><span style="color: #000000; font-weight: bold;">p</span></a>&gt;</span><br />
&nbsp; <span style="color: #009900;">&lt;<a href="http://december.com/html/4/element/p.html"><span style="color: #000000; font-weight: bold;">p</span></a>&gt;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&lt; %<span style="color: #66cc66;">=</span> f.<span style="color: #000066;">label</span> :sub_section_id %&gt;&lt;<a href="http://december.com/html/4/element/br.html"><span style="color: #000000; font-weight: bold;">br</span></a> <span style="color: #66cc66;">/</span>&gt;</span> &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; <span style="color: #009900;">&lt; %<span style="color: #66cc66;">=</span> collection_select<span style="color: #66cc66;">&#40;</span>:gallery, :sub_section_id, SubSection.find_all_by_section_id<span style="color: #66cc66;">&#40;</span>@gallery.section_id<span style="color: #66cc66;">&#41;</span>, :<span style="color: #000066;">id</span>, :<span style="color: #000066;">name</span>, options <span style="color: #66cc66;">=</span><span style="color: #66cc66;">&#123;</span>:<span style="color: #000066;">prompt</span> <span style="color: #66cc66;">=</span>&gt;</span> &quot;&quot;}) %&gt;<br />
&nbsp; <span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><a href="http://december.com/html/4/element/p.html"><span style="color: #000000; font-weight: bold;">p</span></a>&gt;</span><br />
..<br />
<span style="color: #009900;">&lt; % end %&gt;</span></div></td></tr></tbody></table></div>
<p>Again, a fairly typical piece of Rails ERB code for display a html select tag used to create a select list (or drop-down list).  </p>
<p>The collection_select help used for the Section field displays all the valid value Name&#8217;s and stores the id&#8217;s, notes the selected value (as needed in a edit) and a empty string prompt (as needed in a new).</p>
<p>In the case of the Sub Section field the &#8220;extra&#8221; stuff is to populate the drop down for an edit of an exiting value.</p>
<p>That one line &#8220;< %=  collection_select(:gallery, :section_id, Section.all, :id, :name , options ={:prompt => &#8220;&#8221;} ) %>&#8221; replaces all of my 2005 posting <a href="http://www.falsepositives.com/index.php/2005/12/10/building-a-better-drop-down-selection-list-for-ruby-on-rails/">Building a Better Drop Down Selection List for Ruby on Rails</a> written for Rails 1.x.  That&#8217;s progress!!</p>
<p>There&#8217;s the magic sauce for all of this, assuming that you are including the <a href="http://jquery.com/">jQuery</a> javascript library (tested with version jQuery 1.4.2) on the page.  I have this in a partial used in the new and edit pages for the gallery.</p>
<div class="codecolorer-container javascript default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br />26<br />27<br />28<br />29<br />30<br />31<br />32<br />33<br />34<br />35<br />36<br />37<br /></div></td><td><div class="javascript codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #339933;">&lt;</span>script type<span style="color: #339933;">=</span><span style="color: #3366CC;">&quot;text/javascript&quot;</span><span style="color: #339933;">&gt;</span><br />
&nbsp; &nbsp; $<span style="color: #009900;">&#40;</span>document<span style="color: #009900;">&#41;</span>.<span style="color: #660066;">ready</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; $<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;select#gallery_section_id&quot;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">change</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #003366; font-weight: bold;">var</span> id_value_string <span style="color: #339933;">=</span> $<span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">val</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>id_value_string <span style="color: #339933;">==</span> <span style="color: #3366CC;">&quot;&quot;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #006600; font-style: italic;">// if the id is empty remove all the sub_selection options from being selectable and do not do any ajax</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;select#gallery_sub_section_id option&quot;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">remove</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #003366; font-weight: bold;">var</span> row <span style="color: #339933;">=</span> <span style="color: #3366CC;">&quot;&lt;option value=<span style="color: #000099; font-weight: bold;">\&quot;</span>&quot;</span> <span style="color: #339933;">+</span> <span style="color: #3366CC;">&quot;&quot;</span> <span style="color: #339933;">+</span> <span style="color: #3366CC;">&quot;<span style="color: #000099; font-weight: bold;">\&quot;</span>&gt;&quot;</span> <span style="color: #339933;">+</span> <span style="color: #3366CC;">&quot;&quot;</span> <span style="color: #339933;">+</span> <span style="color: #3366CC;">&quot;&lt;/option&gt;&quot;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $<span style="color: #009900;">&#40;</span>row<span style="color: #009900;">&#41;</span>.<span style="color: #660066;">appendTo</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;select#gallery_sub_section_id&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">else</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #006600; font-style: italic;">// Send the request and update sub category dropdown </span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $.<span style="color: #660066;">ajax</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dataType<span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;json&quot;</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; cache<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">false</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; url<span style="color: #339933;">:</span> <span style="color: #3366CC;">'/sub_sections/for_sectionid/'</span> <span style="color: #339933;">+</span> id_value_string<span style="color: #339933;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; timeout<span style="color: #339933;">:</span> <span style="color: #CC0000;">2000</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; error<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>XMLHttpRequest<span style="color: #339933;">,</span> errorTextStatus<span style="color: #339933;">,</span> error<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066;">alert</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;Failed to submit : &quot;</span><span style="color: #339933;">+</span> errorTextStatus<span style="color: #339933;">+</span><span style="color: #3366CC;">&quot; ;&quot;</span><span style="color: #339933;">+</span>error<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; success<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>data<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #006600; font-style: italic;">// Clear all options from sub category select </span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;select#gallery_sub_section_id option&quot;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">remove</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #006600; font-style: italic;">//put in a empty default line</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #003366; font-weight: bold;">var</span> row <span style="color: #339933;">=</span> <span style="color: #3366CC;">&quot;&lt;option value=<span style="color: #000099; font-weight: bold;">\&quot;</span>&quot;</span> <span style="color: #339933;">+</span> <span style="color: #3366CC;">&quot;&quot;</span> <span style="color: #339933;">+</span> <span style="color: #3366CC;">&quot;<span style="color: #000099; font-weight: bold;">\&quot;</span>&gt;&quot;</span> <span style="color: #339933;">+</span> <span style="color: #3366CC;">&quot;&quot;</span> <span style="color: #339933;">+</span> <span style="color: #3366CC;">&quot;&lt;/option&gt;&quot;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $<span style="color: #009900;">&#40;</span>row<span style="color: #009900;">&#41;</span>.<span style="color: #660066;">appendTo</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;select#gallery_sub_section_id&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #006600; font-style: italic;">// Fill sub category select </span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $.<span style="color: #660066;">each</span><span style="color: #009900;">&#40;</span>data<span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>i<span style="color: #339933;">,</span> j<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; row <span style="color: #339933;">=</span> <span style="color: #3366CC;">&quot;&lt;option value=<span style="color: #000099; font-weight: bold;">\&quot;</span>&quot;</span> <span style="color: #339933;">+</span> j.<span style="color: #660066;">sub_section</span>.<span style="color: #660066;">id</span> <span style="color: #339933;">+</span> <span style="color: #3366CC;">&quot;<span style="color: #000099; font-weight: bold;">\&quot;</span>&gt;&quot;</span> <span style="color: #339933;">+</span> j.<span style="color: #660066;">sub_section</span>.<span style="color: #000066;">name</span> <span style="color: #339933;">+</span> <span style="color: #3366CC;">&quot;&lt;/option&gt;&quot;</span><span style="color: #339933;">;</span> &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $<span style="color: #009900;">&#40;</span>row<span style="color: #009900;">&#41;</span>.<span style="color: #660066;">appendTo</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;select#gallery_sub_section_id&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #339933;">&lt;/</span>script<span style="color: #339933;">&gt;</span></div></td></tr></tbody></table></div>
<p>The Code is wrapped up in standard jQuery code for doing unobtrusive javascript, waiting for the DOM to finish load and then watching for changes on the select tag with the gallery_section_id tag id.</p>
<p>The first section of code (lines 5-9) just reacts if the Section field is set to my default prompt of blank, in which case it blanks out the sub section values and does nothing else.</p>
<p>The next piece (line 14-16) is the meat of the <a href="http://api.jquery.com/jQuery.ajax/">$.ajax</a> request: setting the dataType to &#8220;json&#8221; (which ensures the controller routine renders as expected), doing &#8220;cache: false&#8221; is best for development but is someting to look at in production if your supporting data is very very static.  setting the url is Key! in this case &#8221; url: &#8216;/sub_sections/for_sectionid/&#8217; + id_value_string &#8221;  so that it calls the &#8220;sub_sections&#8221; controller and the &#8220;for_sectionid&#8221; routine and passes the id string.</p>
<p>If the ajax returns successfully, then the code removes the exiting option&#8217;s (important! it works on the option part of the DOM) from the sub_section select tag, adds my default blank line, and than append the id and name values from the returned json object.</p>
<p>Using Firefox firebug extension will make your life much easier in debug this, in particular confirming the ajax request fires off the way (and to the url) you expected, and returns what you expect.</p>
<p>Update : thanks to <a href="http://tom.meinlschmidt.org/">Tom Meinlschmidt</a>&#8217;s feedback I&#8217;ve added &#8220;.sort_by{ |k| k['name'] }&#8221; to the function in the sub_sections controller to return the results in order by the sub section name, as it should have been. (and I fixed up a typo!)</p>
]]></content:encoded>
			<wfw:commentRss>http://www.falsepositives.com/index.php/2010/05/28/building-a-casscading-drop-down-selection-list-for-ruby-on-rails-with-jquery-ajax/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Mesh10 : five years of Meshing in Toronto</title>
		<link>http://www.falsepositives.com/index.php/2010/05/21/mesh10-five-years-of-meshing-in-toronto/</link>
		<comments>http://www.falsepositives.com/index.php/2010/05/21/mesh10-five-years-of-meshing-in-toronto/#comments</comments>
		<pubDate>Fri, 21 May 2010 22:49:54 +0000</pubDate>
		<dc:creator>Ian</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Media]]></category>
		<category><![CDATA[Open Source]]></category>
		<category><![CDATA[Social Networking]]></category>
		<category><![CDATA[Toronto]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[Mesh]]></category>
		<category><![CDATA[Mesh10]]></category>

		<guid isPermaLink="false">http://www.falsepositives.com/?p=2568</guid>
		<description><![CDATA[This was the week for MESH and MESH U,which is a Toronto based conference which looks at &#8220;The Web&#8221; and how it is affecting the media, marketing, business and society as a whole.  Mesh is in its 5th year and Mesh U (which is a more focused one for the on design, development and [...]]]></description>
			<content:encoded><![CDATA[<p>This was the week for <a href="http://www.meshconference.com/">MESH </a>and <a href="http://www.meshu.ca/">MESH U</a>,which is a Toronto based conference which looks at &#8220;The Web&#8221; and how it is affecting the media, marketing, business and society as a whole.  Mesh is in its 5th year and Mesh U (which is a more focused one for the on design, development and management people who are building that &#8220;Web&#8221;) is in it&#8217;s second year.</p>
<p>Several thing stood out is this year (my 4th Mesh) :</p>
<ul>
<li>Chris Thorpe, from The Guardian newspaper, did &#8220;Data Chemistry&#8221; (a older version of which is <a href="http://www.slideshare.net/jaggeree/the-new-raw-materials-and-data-chemistry">The New Raw Materials and Data Chemistry</a>)and a Keynote which delved into the work the The Guardian is doing to create a interface allowing full access to the content and / or the data behind that content.  I was not aware of the full breadth and depth of what they were doing.  It was also interesting to near some of the story behind the curtain.  After the conference was the official <a href="http://www.guardian.co.uk/media/pda/2010/may/20/guardian-open-platform">Guardian announces commercial launch of Open Platform</a>.</li>
<li>Diana Clarke, from <a href="http://www.freshbooks.com/">FreshBooks</a> (Online Billing and Bookkeeping) talked about <a href="http://prezi.com/q0t2nxohrd7q/evolve/">Evolving the Platform</a> and how they moved from legacy php to a RESTful python web service.  Excellent!! I use Freshbooks, it always impressed me, and now only more so.</li>
<li>Joseph Menn&#8217;s keynote and <a href="http://fatalsystemerror.org/">book</a> about the new Cyber Crime lord ecology was enlightening and scary.</li>
<li>one of the panel&#8217;s was tapped as part of the TVO&#8217;s <a href="http://www.tvo.org/cfmx/tvoorg/theagenda/">The Agenda</a> in a discussion about the evolution and changing face of privacy in the digital age with Ann Cavoukian, Mathew Ingram, Joseph Menn, Alan Sawyer, David Fewer.<br />
<img style="visibility: hidden; width: 0px; height: 0px;" src="http://counters.gigya.com/wildfire/IMP/CXNID=2000002.0NXC/bT*xJmx*PTEyNzQ*NTE2OTM5OTcmcHQ9MTI3NDQ1MTcxMzE4NSZwPTI2Njc1MSZkPXR2b1ZpZGVvUGFnZSZnPTImbz*yODg3Y2Yx/MmM5NmU*YjhlOGJlOWVjNDZlYjkzZTcyNyZvZj*w.gif" border="0" alt="" width="0" height="0" /><object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="486" height="412" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param name="name" value="flashObj" /><param name="bgcolor" value="#ffffff" /><param name="align" value="middle" /><param name="flashvars" value="videoRefID=86875006001&amp;videoPlay=manual&amp;gig_lt=1274451693997&amp;gig_pt=1274451713185&amp;gig_g=2" /><param name="src" value="http://www.tvo.org/video/tvoMain.swf" /><param name="wmode" value="transparent" /><param name="allowfullscreen" value="true" /><param name="quality" value="high" /><embed type="application/x-shockwave-flash" width="486" height="412" src="http://www.tvo.org/video/tvoMain.swf" quality="high" allowfullscreen="true" wmode="transparent" flashvars="videoRefID=86875006001&amp;videoPlay=manual&amp;gig_lt=1274451693997&amp;gig_pt=1274451713185&amp;gig_g=2" align="middle" bgcolor="#ffffff" name="flashObj"></embed></object></p>
<p>(Link is here for the above <a href="http://www.tvo.org/TVO/WebObjects/TVO.woa?videoid?86875006001"><br />
The Agenda live from Mesh: Canada&#8217;s Web Conference</a>)</p>
<p>FaceBook came in for heavy criticism, with Leigh Honeywell making the best comment of the session!</p>
<p>And yes I&#8217;m like all over the back ground shots.  (Hi Mom! I&#8217;m on Television!!)</li>
<li>The Agenda also tapped 3 interviews form Mesh Speakers : <a href="http://www.tvo.org/cfmx/tvoorg/theagenda/index.cfm?page_id=7&amp;bpn=779787&amp;ts=2010-05-19%2020:00:00.0">Joseph Menn: Fatal System Error | Chris Thorpe: Future of Newspapers | Avril Benoît: Social Media to the Rescue</a>. Very worth watching.</li>
<li>All in all a great conference with lots of insight, and good gut check of what people are doing and where they what to go.   I&#8217;m still recovering and processing.  I got my annual <a href="http://www.rannieturingan.com/events/mesh-portraits-2010/img_9967-2/">Mesh Portrait</a> by the magical Rannie Turingan aka <a href="http://twitter.com/photojunkie">Photo Junkie</a>Also I got to lick an iPad. Yummy. :Q</li>
<li>other writeups for <a href="http://twitter.com/#search?q=%23Mesh">Mesh : </a>
<ul>
<li><a href="http://www.blogto.com/tech/2010/05/mesh_conference_2010_highlights/">BlogTo highlights</a></li>
<li><a href="http://cdblog.centraldesktop.com/2010/05/meshu-2010-wrap-up.html">Isaac Garcia does a wrap up</a></li>
<li>from Digital Journal we have : <a href="http://www.digitaljournal.com/article/292231">mesh 2010: How social media are transforming newsrooms (Includes first-hand account)</a> and <a href="http://www.digitaljournal.com/article/292233">mesh 2010: Dissecting new media&#8217;s &#8216;fast-food content&#8217;</a></li>
<li>Soldier of Code&#8217;s Kaptain Krispy also had a <a href="http://soldierofcode.com/2010/05/20/mesh-2010/">Mesh 2010</a> report</li>
</ul>
<p>this was extracted this from the <a href="http://www.falsepositives.com/index.php/2010/05/21/quick-links-as-of-may-21th-2010/">Quick links as of May 21th 2010</a> post, and expanded.</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.falsepositives.com/index.php/2010/05/21/mesh10-five-years-of-meshing-in-toronto/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Social Networking for Small Businesses</title>
		<link>http://www.falsepositives.com/index.php/2010/04/20/social-networking-for-small-businesses/</link>
		<comments>http://www.falsepositives.com/index.php/2010/04/20/social-networking-for-small-businesses/#comments</comments>
		<pubDate>Tue, 20 Apr 2010 18:56:27 +0000</pubDate>
		<dc:creator>Ian</dc:creator>
				<category><![CDATA[Business]]></category>
		<category><![CDATA[Social Networking]]></category>
		<category><![CDATA[Web]]></category>

		<guid isPermaLink="false">http://www.falsepositives.com/?p=2515</guid>
		<description><![CDATA[This is the result of a couple of conversations I&#8217;ve had with small shop keepers.  They may use some web technologies outside of their business for personal use : ebay, facebook, email, a few e-commerce sites.  They may a iPod or smart phone.  They may have a one page website for the [...]]]></description>
			<content:encoded><![CDATA[<p>This is the result of a couple of conversations I&#8217;ve had with small shop keepers.  They may use some web technologies outside of their business for personal use : ebay, facebook, email, a few e-commerce sites.  They may a iPod or smart phone.  They may have a one page website for the store, and are listed on (one or more) business directories, they don&#8217;t see how a FaceBook page or Twitter is applicable to their business at all.  They are, literally in some cases, &#8220;meat and potato&#8221; &#8220;brick and mortar&#8221; corner stores servicing a very local market.</p>
<p>This got me to thinking of the HOW, WHAT, WHERE, WHEN and WHY  (The 5 W&#8217;s?) of Social Networks for Small Business, and in particular, the small retail business, as apposed to more service orientated businesses.</p>
<p>(this is likely be a expanding list and if you have additional suggestions then make a comment!)</p>
<h3>The HOW.</h3>
<p>So how are they going to do Social Networking?  Probably either via the web browser on their smart phone (in the shop) or on their home computer at home.</p>
<p>They may not have a need for a Internet connection at work because it is so removed from what they do and their customer interaction, or (in the case of some coffee/bake shops) not something they would think of providing to their customers as a service or enticement.</p>
<p>They probably do some bookkeeping and inventory which ends up on the computer but their business are primarily paper based.</p>
<p>Many still have analog cash registers, and not computerized Point of Sells (PoS) systems.  (This might be a cost issue of the hardware software?).  The good news is that mobile computing is becoming easier and cheaper.</p>
<h3>The WHERE</h3>
<p>I would be tempted to lead with Twitter, because its open to all, and it does not take long to write 140 characters, although fitting every into 140 characters can be very challanging.</p>
<p>And then place the same message on a public accessible FaceBook FAN with expended additional text, and an added an image (always good) about the product/person/thing.</p>
<p>I would also have the last several Twitter status messages (Twits) on the your website homepage, done auto-magically via a javascript tool.</p>
<p>You can have interesting discussion, (and a whole other posting) about if you need a web page at all now.  At most these businesses might have a who are we, where are we, &#8220;when we are (our hours), &#8220;what are we&#8221; (our products, possibly just a high level list of products or suppliers).  So 2 to X pages where X is a single digit. &#8220;who&#8221; and &#8220;what&#8221; can collapsed, as can &#8220;When&#8221; and &#8220;where&#8221;.  The &#8220;what can be expanded to considerable details but be careful.</p>
<p>You might get away with only a FaceBook FAN page, if it&#8217;s open to Google but I&#8217;m a little nervous about putting to much of your on line marketing presence in FaceBook&#8217;s owned garden.  From a medium to long term Marketing and Branding angle it just looks like a bad idea.  But very short term is okay.</p>
<p>You probably don&#8217;t need to edit your company website more that once a year or season (for Seasonal product), but you do need to keep it up to date when things change.  If you can&#8217;t update your web site content as easily as your FaceBook FAN page, your doing it wrong.  One of the nice things about showing your Twitter stream on the home page (or on a side bar) is it is a trivially easy way to keep some fresh content on the web site.</p>
<p>It would be good to become aware of location based sites like of Yelp and Urban Spoon (or other in your category) as well a the newest up and comers FourSqure and GoWalla.</p>
<p>Seek out and learn about tools that let you know when other people mention you, and your brand.</p>
<p>Your Website should be usable on a mobile web browser.  That means to allows for appropriate size and styling, and no flash! (restaurants and hotels are really bad at this!)</p>
<h3>The WHAT.</h3>
<p>What should you be messaging on?</p>
<ul>
<li>The arrival of new products, a special shipment or season item.</li>
<li>Your having a sale.</li>
<li>You had to close the store temporally due to : medical emergency; water/gas leak; a holiday.  But you will be open tomorrow!! (please visit)</li>
<li>You are back from the Holiday, hope you enjoyed yours and am eager to service you!</li>
<li>You are all out of stock, but more will be in on Monday! (don&#8217;t you wish you had come by earlier?  Don&#8217;t worry you too can get one of these popular things on Monday, While supplies last)</li>
<li>Wish Dave a happy birthday and get a discount.</li>
<li>The First 4 people to say the secret word today, get a free Gadget-Thingy!!</li>
<li>This wonderful event is happening in the neighborhood! Check it out! (don&#8217;t we live/work in a great place?)</li>
<li>The store next door is having a promotion! (and come  visit us too!)</li>
<li>We were mentioned in the local/national newspaper (with the link to the mention).</li>
<li>Here&#8217;s a interesting Fact about something we sell, it&#8217;s name comes from A meaning B, or it&#8217;s made from solvent green!!</li>
<li>Sharing information about your industry.</li>
<li>Re Twitter things that other people Twitted about your business or the neighbor. (and thank them)</li>
<li>Regular customer Sue is doing this big deal thing</li>
<p><em>Don&#8217;t</em> be purely promoting your self, that is &#8220;traditional&#8221; marketing and quickly becomes being seen as spam.  <em>Do</em> promote your neighbors and neighborhood, your customers; and promote your &#8220;industry&#8221; and peers.  Grow the pie, not (just) your piece of it.</p>
<p>You can do this in a funny manner, just be careful they share or understand your sense of humour.  It should be done in a informal tone. Make it a win for your customers.  Over all, it should be Sincere, Positive, and it should be you.</p>
<h3>The WHEN.</h3>
<p>This is a function of the HOW and the WHAT : At most daily (except for emergencies. and likely done at the beginning or the end of the work day.</p>
<p>Of course, the lack of time is another reason these business don&#8217;t do &#8220;Social Networking&#8221;).  Try to do it at minimum weekly (this is where the neighbourhood stuff and interesting facts come in handy) and never never less than monthly.   Try doing a little learning about this &#8220;Social Networking&#8221; every day/week or month.   It is a challenge to do these, when running your business is a full time job (or more).  Ask for help!  Pay someone (like me) for help!</p>
<h3>The WHY.</h3>
<p>Social Networking, done well, is the most cost effective advertising and marketing available.</p>
<ul>
<li>Give them a reason to visit you.</li>
<li>Exceed their expectations;</li>
<li>Do not disappoint your customers (and potential customers);</li>
<li>Telling them your story and how your are different; but a face to your business.</li>
<li>Experiment, but remember the &#8220;Golden Rule&#8221; (Treat others as you would wish to be treated).</li>
<li>Showing them you are connected to the place(s) you share.</li>
<li>Be Patient.</li>
<li>Generate positive word of mouth.</li>
</ul>
<p>People are -probably- already talking about you, if you know about it you can : learn from listening, apologies for mistakes; correct errors; inform and educate; connect.</p>
<p>It&#8217;s all about being Social!</p>
</ul>
<h3>June 14 update</h3>
<p>Mashable post <a href="http://mashable.com/2010/06/13/small-business-advice/">Why Small Businesses Shouldn’t Take Social Media for Granted</a> makes some good points, including : &#8220;Simple Works&#8221;, and &#8220;Your Size Works in Your Favor&#8221; and makes a great suggestion :  </p>
<blockquote><p>Who are your most frequent customers? Make a Twitter List called “Regulars,” and add your regulars on Twitter to it.</p></blockquote>
<p>To which I would add making a Twitter list of your (premium) suppliers!  </p>
]]></content:encoded>
			<wfw:commentRss>http://www.falsepositives.com/index.php/2010/04/20/social-networking-for-small-businesses/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>IE 6 Death Watch gets a Funeral Service and at least a few more Nails in it&#8217;s coffin</title>
		<link>http://www.falsepositives.com/index.php/2010/02/23/ie-6-death-watch-gets-a-funeral-service-and-at-least-a-few-more-nails/</link>
		<comments>http://www.falsepositives.com/index.php/2010/02/23/ie-6-death-watch-gets-a-funeral-service-and-at-least-a-few-more-nails/#comments</comments>
		<pubDate>Tue, 23 Feb 2010 19:52:57 +0000</pubDate>
		<dc:creator>Ian</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Web]]></category>

		<guid isPermaLink="false">http://www.falsepositives.com/?p=2454</guid>
		<description><![CDATA[Part 2.
 Six Months ago I declared One Year to Go on the IE 6 Deathwatch
In the beginning of this year it was disclosed that Google (as well as and 20+ other companies) had been the victim of Chinese cyber attack, attackers called the operation “Aurora” .  Microsoft had admitted that Explorer was used [...]]]></description>
			<content:encoded><![CDATA[<p>Part 2.<br />
<img src="http://www.falsepositives.com/wp-content/uploads/2010/03/ie6_logo_small.jpg" alt="" /> Six Months ago I declared <a href="http://www.falsepositives.com/index.php/2009/07/14/ie-6-deathwatch/">One Year to Go on the IE 6 Deathwatch</a></p>
<p>In the beginning of this year it was disclosed that Google (as well as and 20+ other companies) had been the victim of Chinese cyber attack, attackers called the operation “Aurora” .  Microsoft had admitted that Explorer was used in Google China hack (via <a href="http://news.bbc.co.uk/2/hi/8460819.stm">BBC</a>), and it now known that the attack took advantage of a zero-day vulnerability in Internet Explorer 6 &#8211; <a href="http://www.microsoft.com/technet/security/advisory/979352.mspx">CVE-2010-0249</a> &#8211; to drop malware onto compromised systems. (via <a href="http://www.theregister.co.uk/2010/01/19/google_china_attack_malware_analysis/">The Register</a>)</p>
<p>This has <a href="http://www.readwriteweb.com/archives/to_switch_or_not_to_switch_debating_the_internet_e.php">promoted </a>France,  Germany (and then Australia) to suggesting that its citizens switch from Internet Explorer. </p>
<p>Thomas Kristensen, the chief security officer for Secunia a company that specializes in looking for security vulnerabilities, commented :<br />
<blockquote>
&#8220;Currently it is evident that running IE6 on XP or Windows 2000 is a very bad idea, and any other browser would be a better choice for XP and Windows 2000 users,&#8221; </p></blockquote>
<p>
In other news : </p>
<p>Goggle has announced <a href="http://googleenterprise.blogspot.com/2010/01/modern-browsers-for-modern-applications.html">Modern Browsers for Modern Applications</a>  declaring :</p>
<blockquote><p>Many other companies have already stopped supporting older browsers like Internet Explorer 6.0 as well as browsers that are not supported by their own manufacturers. We’re also going to begin phasing out our support, starting with Google Docs and Google Sites. As a result you may find that from March 1 key functionality within these products &#8212; as well as new Docs and Sites features &#8212; won’t work properly in older browsers.</p></blockquote>
<p>But more importantly, <a href="http://www.google.com/support/youtube/bin/answer.py?hl=en&#038;answer=175292">Google-owned YouTube will end support for Internet Explorer 6 on March 13</a>, just two weeks after ending support on Google Docs. </p>
<p>This will have the effect of getting many non corporate users to upgrdae their browsers off of IE6, and more than a few off of Internet Explorer altogether.</p>
<p>This has lead to the <a href="http://ie6funeral.com/">announcement</a> that &#8220;Internet Explorer Six, resident of the interwebs for over 8 years, died the morning of March 1, 2010 in Mountain View, California, as a result of a workplace injury sustained at the headquarters of Google, Inc.&#8221;</p>
<p>Hence, a funeral services for Internet Explorer Six will be held at 7pm on March 4, in Denver, Colorado.</p>
<p>Can someone be sure to put a stake in it&#8217;s heart to ensure it does not come back? <img src='http://www.falsepositives.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>It&#8217;s still the most dreaded 3 letters in a web developers life. </p>
<p>Beta New just published (March 1) <a href="http://www.betanews.com/joewilcox/article/Let-the-Internet-Explorer-6-death-watch-begin/1267468004">Let the Internet Explorer 6 death watch begin</a> will many amusing statements :</p>
<blockquote><p>IE6&#8217;s heart turned evil long ago. .. During IE6&#8217;s reign of terror Website designers paid tribute by using a DOCTYPE ..  Meanwhile, IE6 amassed a great group of worshipers &#8212; malware writers looking to exploit security vulnerabilities for profit. .. IE6 will be missed by malware worshipers and enterprise IT managers too dependent on ActiveX controls to easily switch browsers. </p></blockquote>
<p>(and how soon till we can start the &#8220;Flash Death Watch&#8221;? It&#8217;s the IE6 of the 10&#8217;s!)</p>
<p>Update March 5th : Post ie6 funeral report: <a href="http://techcrunch.com/2010/03/05/ie6-funeral">IE6 Laid To Rest. Pictures, Videos, And Flowers From Microsoft.</a> and Protesters (!?!).</p>
<p>And see CSS Squirrel, Kyle Weems, for <a href="http://www.cssquirrel.com/comic/?comic=57">Goodbye, Six, and good riddance. So Say We All!</a> and <a href="http://www.cssquirrel.com/2010/03/10/comic-update-so-say-we-all/trackback/">then read the related blog post</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.falsepositives.com/index.php/2010/02/23/ie-6-death-watch-gets-a-funeral-service-and-at-least-a-few-more-nails/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>different behavior for Prototype JavaScript childElements() in FF and IE</title>
		<link>http://www.falsepositives.com/index.php/2010/02/19/different-behavior-for-prototype-javascript-childelements-in-ff-and-ie/</link>
		<comments>http://www.falsepositives.com/index.php/2010/02/19/different-behavior-for-prototype-javascript-childelements-in-ff-and-ie/#comments</comments>
		<pubDate>Fri, 19 Feb 2010 20:26:01 +0000</pubDate>
		<dc:creator>Ian</dc:creator>
				<category><![CDATA[Ajax]]></category>
		<category><![CDATA[Code]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Web]]></category>

		<guid isPermaLink="false">http://www.falsepositives.com/?p=1384</guid>
		<description><![CDATA[Or now to lose the rest of one&#8217;s limited hair     &#8230;. I&#8217;ve come across a &#8220;doesn&#8217;t work as expect&#8221; issue while working in Prototype 1.6.0.2 JavaScript framework (&#8221;Easy Ajax and DOM manipulation for dynamic web applications&#8221; for sure!)
1$('someIdName').parentNode.childElements()
works fine in FireFox (v3) but not in Internet Explorer ( v6), in particular it seems [...]]]></description>
			<content:encoded><![CDATA[<p>Or now to lose the rest of one&#8217;s limited hair  <img src='http://www.falsepositives.com/wp-includes/images/smilies/icon_sad.gif' alt=':(' class='wp-smiley' />   &#8230;. I&#8217;ve come across a &#8220;doesn&#8217;t work as expect&#8221; issue while working in <a href="http://www.prototypejs.org/" rel="tag">Prototype 1.6.0.2 JavaScript framework</a> (&#8221;Easy Ajax and DOM manipulation for dynamic web applications&#8221; for sure!)</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">$('someIdName').parentNode.childElements()</div></td></tr></tbody></table></div>
<p>works fine in FireFox (v3) but not in Internet Explorer ( v6), in particular it seems the the</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">$('someIdName').childElements()</div></td></tr></tbody></table></div>
<p>fails giving a &#8220;Object doesn&#8217;t support this property or method&#8221;</p>
<p>thankfully</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">$('someIdName').siblings()</div></td></tr></tbody></table></div>
<p>worked just fine. <img src='http://www.falsepositives.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  but I still worried about the Fail.</p>
<p>I think the problem was that in some cases the</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&quot;ParentNode&quot;</div></td></tr></tbody></table></div>
<p>was a</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&quot;div&quot;</div></td></tr></tbody></table></div>
<p>element and strictly speaking Div&#8217;s do have children. Is this a difference in the DOM between IE and FF?</p>
<p>perhaps $(&#8217;someIdName&#8217;).parentNode.childNodes would work?</p>
]]></content:encoded>
			<wfw:commentRss>http://www.falsepositives.com/index.php/2010/02/19/different-behavior-for-prototype-javascript-childelements-in-ff-and-ie/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>a GreaseMonkey script for Follow Rank and Follows in Common for Twitter User Profiles</title>
		<link>http://www.falsepositives.com/index.php/2010/01/28/a-greasemonkey-script-for-follow-rank-and-follows-in-common-for-twitter-user-profiles/</link>
		<comments>http://www.falsepositives.com/index.php/2010/01/28/a-greasemonkey-script-for-follow-rank-and-follows-in-common-for-twitter-user-profiles/#comments</comments>
		<pubDate>Thu, 28 Jan 2010 16:48:33 +0000</pubDate>
		<dc:creator>Ian</dc:creator>
				<category><![CDATA[GreaseMonkey]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Social Networking]]></category>
		<category><![CDATA[Web]]></category>

		<guid isPermaLink="false">http://www.falsepositives.com/?p=2377</guid>
		<description><![CDATA[I&#8217;ve released  a GreaseMonkey script Follow Rank and Follows in Common for Twitter User Profiles which you can use to display the Follows in Common and the Follow Rank for a given users profile page and discover how important they are in your Twitter Social Network.
Similar in aim to FaceBooks &#8220;friends in common&#8221;, adjusted [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve released  a GreaseMonkey script <a href="http://userscripts.org/scripts/show/64286">Follow Rank and Follows in Common for Twitter User Profiles</a> which you can use to display the Follows in Common and the Follow Rank for a given users profile page and discover how important they are in your Twitter Social Network.</p>
<p>Similar in aim to FaceBooks &#8220;friends in common&#8221;, adjusted to reflect twitter&#8217;s asymmetrical following as opposed to FaceBooks symmetrical Friending.  i.e. in Facebook we both have to agree to be &#8220;Friends&#8221;, but it Twitter it only takes one of us to follow the other, following back is optional.</p>
<p>It order to use this script you need to have the <a href="http://addons.mozilla.org/en-US/firefox/addon/748">GreaseMonkey extension</a> installed, add the script, and then go to a users profile page on Twitter.com, like <a href="http://twitter.com/scobleizer">Robert Scoble</a>&#8217;s twitter page, (or <a href="http://twitter.com/aplusk">Ashton Kutcher</a>&#8217;s!)</p>
<p>FollowRank tells you how many, and which, of the people you follow are also following Robert Scoble (or Ashton Kutcher).</p>
<p>Follows in Common tells you how many, and which, of the people you follow are also followed by Robert Scoble (or Ashton Kutcher).</p>
<p>If you look at your own profile you will see a) 100% Follows in Common, b) How many of the people you follow who follow you back!</p>
<p><img src="http://s3.amazonaws.com/uso_ss/5578/large.jpg?1264695558" alt="Robert Scoble with Follow Rank and FiC GM Script" /></p>
<p>Notice the small gray down arrows? (This is visible if the result is none zero.) Clicking on the text line will reveal the avatar picture of the people who contribute to the score.  Hovering over the picture will show their name and clicking on it open their user profile page (and compute their Follow Rank and Follows in Common).<br />
<img src="http://s3.amazonaws.com/uso_ss/5579/large.jpg?1264696525" alt="Robert Scoble with Follow Rank and FiC GM Scrip showing People" /><br />
Clicking on the text line a second time (see the small gray up arrows?) will collapse the view of Follow Rank or Follows in Common user avatar&#8217;s.  The data is cached so reopening the view is super fast.</p>
<h4>So Why Follow Rank?</h4>
<p>This information lets me know this persons relevance and weight in my social network, the people I have choicen to follow (my first Order Social Network in Twitter).</p>
<p>It lets me know, quickly, why they discovered me, or why I might follow them.</p>
<h4>How am I doing this?</h4>
<p>All JavaScript, using the Twitter&#8217;s API calls for their Social Graph Methods (<a href="http://apiwiki.twitter.com/Twitter%20REST%20API%20Method:%20friends%C2%A0ids">Twitter REST API Method: friends ids</a> and <a href="http://apiwiki.twitter.com/Twitter-REST-API-Method%3A-followers%C2%A0ids">Twitter REST API Method: followers ids</a>), lots of caching of results (but only for a period of time using my <a href="http://www.falsepositives.com/index.php/2009/12/15/using-greasemonkey%E2%80%99s-persistent-data-functions-as-a-aged-cache-revised/">aged Cache function</a> &#8211; persistent, but not too  persistent!!   ) to get around the Twitter throttle limit (currently ~150 requests per hour limit, see <a href="http://apiwiki.twitter.com/Rate-limiting">Rate limiting</a>), and lots of JSON AJAX calls of those api calls.   Plus, taking advantage of Twitters.com&#8217;s use of <a href="http://jquery.com/">jQuery</a> on their web pages, their own plug-in&#8217;s and css and images.  Easy!!</p>
<h4>What&#8217;s next</h4>
<p>There is still work to be done and features to be added add to the GM script (LiC : Lists in Common?), and then to go beyond what can be done in a GreaseMonkey script!</p>
<p>I&#8217;m thinking of exposing your 2nd order Twitter Social Network : Who are the people being followed by the people you follow?  What&#8217;s their Follow Rank? Also, who of them follows almost the same people who follow?</p>
<p>I think this would make a organic &#8220;Suggested Users List&#8221;, personalized just for you because it based on your social network.</p>
<p>Now do that for your -1 &amp; -2 order networks.</p>
<p>Plus sorting (by alpha, by Follow Rank, by FiC), and searching of all that.</p>
<p>This will keep me busy!  Whatcha think?</p>
]]></content:encoded>
			<wfw:commentRss>http://www.falsepositives.com/index.php/2010/01/28/a-greasemonkey-script-for-follow-rank-and-follows-in-common-for-twitter-user-profiles/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Using GreaseMonkey’s persistent data functions as a aged Cache, revised.</title>
		<link>http://www.falsepositives.com/index.php/2009/12/15/using-greasemonkey%e2%80%99s-persistent-data-functions-as-a-aged-cache-revised/</link>
		<comments>http://www.falsepositives.com/index.php/2009/12/15/using-greasemonkey%e2%80%99s-persistent-data-functions-as-a-aged-cache-revised/#comments</comments>
		<pubDate>Tue, 15 Dec 2009 19:04:25 +0000</pubDate>
		<dc:creator>Ian</dc:creator>
				<category><![CDATA[Ajax]]></category>
		<category><![CDATA[Code]]></category>
		<category><![CDATA[GreaseMonkey]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Web]]></category>

		<guid isPermaLink="false">http://www.falsepositives.com/?p=2328</guid>
		<description><![CDATA[In eating my own dog food I have revised, corrected, improved and fixed the code I posted last week.  The biggest changes are related to ensuring that all that cached data does not just accumulate and never gets cleared away.
Values set using the &#8220;GM_setValue&#8221; function are saved in the Firefox preferences back end and [...]]]></description>
			<content:encoded><![CDATA[<p>In eating my own dog food I have revised, corrected, improved and fixed <a href="http://www.falsepositives.com/index.php/2009/12/09/use-greasemonkeys-persistent-data-functions-as-a-aged-cache/">the code I posted last week</a>.  The biggest changes are related to ensuring that all that cached data does not just accumulate and never gets cleared away.</p>
<p>Values set using the &#8220;GM_setValue&#8221; function are saved in the Firefox preferences back end and can be manually changed by typing &#8220;about:config&#8221; in the address bar and searching for the preference name &#8220;greasemonkey.scriptvals.namespace/name.foo&#8221; or the key that you set.</p>
<div class="codecolorer-container javascript default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;height:400px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br />26<br />27<br />28<br />29<br />30<br />31<br />32<br />33<br />34<br />35<br />36<br />37<br />38<br />39<br />40<br />41<br />42<br />43<br />44<br />45<br />46<br />47<br />48<br />49<br />50<br />51<br />52<br />53<br />54<br />55<br />56<br />57<br />58<br />59<br />60<br />61<br />62<br />63<br />64<br />65<br />66<br />67<br />68<br />69<br />70<br />71<br />72<br />73<br />74<br />75<br />76<br />77<br />78<br />79<br />80<br />81<br />82<br />83<br />84<br />85<br />86<br />87<br />88<br />89<br />90<br />91<br />92<br />93<br />94<br />95<br />96<br />97<br />98<br />99<br />100<br />101<br />102<br />103<br />104<br />105<br />106<br />107<br />108<br />109<br />110<br />111<br />112<br />113<br />114<br />115<br />116<br />117<br />118<br />119<br />120<br />121<br />122<br />123<br />124<br />125<br />126<br />127<br />128<br />129<br />130<br />131<br />132<br />133<br />134<br />135<br />136<br />137<br />138<br />139<br />140<br />141<br />142<br />143<br />144<br />145<br />146<br />147<br />148<br />149<br />150<br />151<br />152<br />153<br />154<br />155<br />156<br />157<br />158<br />159<br />160<br />161<br />162<br />163<br />164<br />165<br /></div></td><td><div class="javascript codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&nbsp; &nbsp; <span style="color: #003366; font-weight: bold;">var</span> MaxCacheAge <span style="color: #339933;">=</span> <span style="color: #CC0000;">60</span> <span style="color: #339933;">*</span> <span style="color: #CC0000;">60</span> <span style="color: #339933;">*</span> <span style="color: #CC0000;">24</span> <span style="color: #339933;">*</span> <span style="color: #CC0000;">1000</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// Max Age for the Cached data is 1 day in milliseconds</span><br />
&nbsp; &nbsp; <span style="color: #003366; font-weight: bold;">var</span> currentTime <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> Date<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">valueOf</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> &nbsp;<span style="color: #006600; font-style: italic;">// current datetime in milliseconds</span><br />
<br />
&nbsp; &nbsp; <span style="color: #003366; font-weight: bold;">function</span> getIntersect<span style="color: #009900;">&#40;</span>arr1<span style="color: #339933;">,</span> arr2<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #006600; font-style: italic;">/**<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* given 2 arrays returns an array with all elements in arr1 that are in arr2<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* see http://www.falsepositives.com/index.php/2009/12/01/javascript-function-to-get-the-intersect-of-2-arrays/ for more details<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;*/</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #003366; font-weight: bold;">var</span> r <span style="color: #339933;">=</span> <span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> o <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span><span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span> l <span style="color: #339933;">=</span> arr2.<span style="color: #660066;">length</span><span style="color: #339933;">,</span> i<span style="color: #339933;">,</span> v<span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span>i <span style="color: #339933;">=</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">;</span> i <span style="color: #339933;">&lt;</span> l<span style="color: #339933;">;</span> i<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; o<span style="color: #009900;">&#91;</span>arr2<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">true</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; l <span style="color: #339933;">=</span> arr1.<span style="color: #660066;">length</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span>i <span style="color: #339933;">=</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">;</span> i <span style="color: #339933;">&lt;</span> l<span style="color: #339933;">;</span> i<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; v <span style="color: #339933;">=</span> arr1<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>v <span style="color: #000066; font-weight: bold;">in</span> o<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; r.<span style="color: #660066;">push</span><span style="color: #009900;">&#40;</span>v<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">return</span> r<span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span style="color: #003366; font-weight: bold;">function</span> Array_diff<span style="color: #009900;">&#40;</span>arr1<span style="color: #339933;">,</span> arr2<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #006600; font-style: italic;">/**<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* given 2 arrays returns an array with all elements in arr1 that are NOT in arr2<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;*/</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #003366; font-weight: bold;">var</span> r <span style="color: #339933;">=</span> <span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> o <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span><span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span> l <span style="color: #339933;">=</span> arr2.<span style="color: #660066;">length</span><span style="color: #339933;">,</span> i<span style="color: #339933;">,</span> v<span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span>i <span style="color: #339933;">=</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">;</span> i <span style="color: #339933;">&lt;</span> l<span style="color: #339933;">;</span> i<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; o<span style="color: #009900;">&#91;</span>arr2<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">true</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; l <span style="color: #339933;">=</span> arr1.<span style="color: #660066;">length</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span>i <span style="color: #339933;">=</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">;</span> i <span style="color: #339933;">&lt;</span> l<span style="color: #339933;">;</span> i<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; v <span style="color: #339933;">=</span> arr1<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #009900;">&#40;</span>v <span style="color: #000066; font-weight: bold;">in</span> o<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; r.<span style="color: #660066;">push</span><span style="color: #009900;">&#40;</span>v<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">return</span> r<span style="color: #339933;">;</span> &nbsp; &nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
<br />
<br />
<span style="color: #006600; font-style: italic;">/**<br />
&nbsp;* add key to the array of values we are tracking (if it's not aready there)<br />
&nbsp;* @param {string} key<br />
&nbsp;*/</span><br />
<span style="color: #003366; font-weight: bold;">function</span> GM_setCachedDataTrackingValueKey<span style="color: #009900;">&#40;</span>key<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #003366; font-weight: bold;">var</span> Tracking <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">eval</span><span style="color: #009900;">&#40;</span>GM_getValue<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'CachedDataTracking_cache'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">&quot;&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>Tracking <span style="color: #339933;">==</span> <span style="color: #3366CC;">&quot;&quot;</span> <span style="color: #339933;">||</span> Tracking <span style="color: #339933;">==</span> undefined<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #003366; font-weight: bold;">var</span> Tracking <span style="color: #339933;">=</span> <span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; <span style="color: #003366; font-weight: bold;">var</span> i<span style="color: #339933;">,</span> l <span style="color: #339933;">=</span> Tracking.<span style="color: #660066;">length</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span>i <span style="color: #339933;">=</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">;</span> i <span style="color: #339933;">&lt;</span> l<span style="color: #339933;">;</span> i<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>Tracking<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span> <span style="color: #339933;">===</span> key<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #3366CC;">&quot;&quot;</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// the key is already in the Tracking array so we can stop;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; Tracking.<span style="color: #660066;">push</span><span style="color: #009900;">&#40;</span>key<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; GM_setValue<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'CachedDataTracking_cache'</span><span style="color: #339933;">,</span> uneval<span style="color: #009900;">&#40;</span>Tracking<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; <br />
<span style="color: #009900;">&#125;</span><br />
<br />
<span style="color: #003366; font-weight: bold;">function</span> GM_removeCachedDataTrackingValueKey<span style="color: #009900;">&#40;</span>key<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; console.<span style="color: #660066;">log</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'GM_removeCachedDataTrackingValueKey,key='</span> <span style="color: #339933;">+</span> key<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #003366; font-weight: bold;">var</span> Tracking <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">eval</span><span style="color: #009900;">&#40;</span>GM_getValue<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'CachedDataTracking_cache'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">&quot;&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>Tracking <span style="color: #339933;">==</span> <span style="color: #3366CC;">&quot;&quot;</span> <span style="color: #339933;">||</span> Tracking <span style="color: #339933;">==</span> undefined<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #3366CC;">&quot;&quot;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; <span style="color: #003366; font-weight: bold;">var</span> i<span style="color: #339933;">,</span> l <span style="color: #339933;">=</span> Tracking.<span style="color: #660066;">length</span><span style="color: #339933;">,</span> NewTracking <span style="color: #339933;">=</span> <span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> j <span style="color: #339933;">=</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span>i <span style="color: #339933;">=</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">;</span> i <span style="color: #339933;">&lt;</span> l<span style="color: #339933;">;</span> i<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>Tracking<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span> <span style="color: #339933;">!=</span> key<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; NewTracking<span style="color: #009900;">&#91;</span>j<span style="color: #339933;">++</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> Tracking<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span> &nbsp; &nbsp;<br />
&nbsp; &nbsp; GM_setValue<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'CachedDataTracking_cache'</span><span style="color: #339933;">,</span> uneval<span style="color: #009900;">&#40;</span>NewTracking<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; GM_deleteValue<span style="color: #009900;">&#40;</span>key<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #009900;">&#125;</span><br />
<br />
<span style="color: #006600; font-style: italic;">/**<br />
&nbsp;* delete all cached values older than MaxCacheAge<br />
&nbsp;* @param {Number} MaxCacheAge 0=all. Required.<br />
&nbsp;*/</span><br />
<span style="color: #003366; font-weight: bold;">function</span> GM_flushCachedData<span style="color: #009900;">&#40;</span>MaxCacheAge<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<br />
&nbsp; &nbsp; <span style="color: #003366; font-weight: bold;">var</span> Tracking <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">eval</span><span style="color: #009900;">&#40;</span>GM_getValue<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'CachedDataTracking_cache'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">&quot;&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #009900;">&#40;</span>Tracking <span style="color: #339933;">==</span> <span style="color: #3366CC;">&quot;&quot;</span> <span style="color: #339933;">||</span> Tracking <span style="color: #339933;">==</span> undefined<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> &nbsp; &nbsp; &nbsp; &nbsp;<br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #003366; font-weight: bold;">var</span> l <span style="color: #339933;">=</span> Tracking.<span style="color: #660066;">length</span><span style="color: #339933;">,</span> i<span style="color: #339933;">,</span> v<span style="color: #339933;">,</span> who<span style="color: #339933;">,</span> DeleteWhoFromTracking <span style="color: #339933;">=</span> <span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span> &nbsp; &nbsp; &nbsp; &nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span>i <span style="color: #339933;">=</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">;</span> i <span style="color: #339933;">&lt;</span> l<span style="color: #339933;">;</span> i<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; who <span style="color: #339933;">=</span> Tracking<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #003366; font-weight: bold;">var</span> DateofWho <span style="color: #339933;">=</span> GM_getValue<span style="color: #009900;">&#40;</span>who <span style="color: #339933;">+</span> <span style="color: #3366CC;">'_cacheDate'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">&quot;&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// get the age of the cache for Who </span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>DateofWho <span style="color: #339933;">!=</span> <span style="color: #3366CC;">&quot;&quot;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>MaxCacheAge <span style="color: #339933;">==</span> <span style="color: #CC0000;">0</span> <span style="color: #339933;">||</span> <span style="color: #009900;">&#40;</span>DateofWho <span style="color: #339933;">&lt;</span> <span style="color: #009900;">&#40;</span>currentTime <span style="color: #339933;">-</span> MaxCacheAge<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> &nbsp; <span style="color: #006600; font-style: italic;">// if age is older that MaxCacheAge </span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #006600; font-style: italic;">//the blank the date and the data and remove from CachedDataTracking_cache</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; GM_deleteValue<span style="color: #009900;">&#40;</span>who<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; GM_deleteValue<span style="color: #009900;">&#40;</span>who <span style="color: #339933;">+</span> <span style="color: #3366CC;">'_cacheDate'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">&quot;&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; DeleteWhoFromTracking.<span style="color: #660066;">push</span><span style="color: #009900;">&#40;</span>who<span style="color: #009900;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>DeleteWhoFromTracking.<span style="color: #660066;">length</span> <span style="color: #339933;">&gt;</span> <span style="color: #CC0000;">0</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> <span style="color: #006600; font-style: italic;">// if there is anyone to remove from tracking</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #003366; font-weight: bold;">var</span> NewTracking <span style="color: #339933;">=</span> Array_diff<span style="color: #009900;">&#40;</span>Tracking<span style="color: #339933;">,</span> DeleteWhoFromTracking<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">//NewTracking is new array minus element from 2nd array &nbsp; &nbsp; &nbsp; &nbsp;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>NewTracking.<span style="color: #660066;">length</span> <span style="color: #339933;">==</span> <span style="color: #CC0000;">0</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; GM_setValue<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'CachedDataTracking_cache'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">&quot;&quot;</span><span style="color: #009900;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">else</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; GM_setValue<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'CachedDataTracking_cache'</span><span style="color: #339933;">,</span> uneval<span style="color: #009900;">&#40;</span>NewTracking<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span> &nbsp; &nbsp; &nbsp; &nbsp;<br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
GM_setValue<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'CachedDataTracking_cacheDate'</span><span style="color: #339933;">,</span> currentTime<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #009900;">&#125;</span><br />
<br />
<br />
&nbsp; <span style="color: #006600; font-style: italic;">/**<br />
&nbsp; &nbsp; &nbsp;* GM_setCachedDataValue set the value, using the key name, and the cacheDate for the value based on the current datetime.<br />
&nbsp; &nbsp; &nbsp;* to see the values set use about:config in the firefox awsome bar and filter with greasemonkey.scriptvals.http://www.FollowRank.com/<br />
&nbsp; &nbsp; &nbsp;* @param {String} key &nbsp;The key argument is a string of no fixed format. &nbsp;Required. &nbsp;<br />
&nbsp; &nbsp; &nbsp;* @param {Object} value The value argument can be a string, boolean, or integer. Required.<br />
&nbsp; &nbsp; &nbsp;* @returns void<br />
&nbsp; &nbsp; &nbsp;*<br />
&nbsp; &nbsp; &nbsp;*/</span><br />
&nbsp; &nbsp; <span style="color: #003366; font-weight: bold;">function</span> GM_setCachedDataValue<span style="color: #009900;">&#40;</span>key<span style="color: #339933;">,</span> value<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #006600; font-style: italic;">// key is the name of the value stored</span><br />
&nbsp; &nbsp; <span style="color: #006600; font-style: italic;">// value is the value to be stored</span><br />
&nbsp; &nbsp; <span style="color: #003366; font-weight: bold;">var</span> currentTime <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> Date<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">valueOf</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #003366; font-weight: bold;">var</span> raw <span style="color: #339933;">=</span> currentTime.<span style="color: #660066;">valueOf</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; GM_setValue<span style="color: #009900;">&#40;</span>key<span style="color: #339933;">,</span> value<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; GM_setValue<span style="color: #009900;">&#40;</span>key <span style="color: #339933;">+</span> <span style="color: #3366CC;">'_cacheDate'</span><span style="color: #339933;">,</span> raw.<span style="color: #660066;">toString</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #009900;">&#125;</span><br />
<br />
&nbsp; &nbsp; <span style="color: #006600; font-style: italic;">/**<br />
&nbsp; &nbsp; &nbsp;* GM_getCachedDataValue returns the value indicated by the key if a) it exists, b) if it is less the maxDuration milliseconds old; otherwise return a blank.<br />
&nbsp; &nbsp; &nbsp;* @param {String} key key is the name of the value stored. key argument is a string of no fixed format. &nbsp;Required.<br />
&nbsp; &nbsp; &nbsp;* @param {Number} maxDuration is the &nbsp;Maximum Duration (or how old) in milliseconds the cached data can be. maxDuration is a number. Required.<br />
&nbsp; &nbsp; &nbsp;* @returns a Integer, String or Boolean<br />
&nbsp; &nbsp; &nbsp;*/</span><br />
<span style="color: #003366; font-weight: bold;">function</span> GM_getCachedDataValue<span style="color: #009900;">&#40;</span>key<span style="color: #339933;">,</span> maxDuration<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #006600; font-style: italic;">// key is the name of the value stored</span><br />
&nbsp; &nbsp; <span style="color: #006600; font-style: italic;">// maxDuration is Maximum Duration (or how old) in milliseconds the cached data can be</span><br />
&nbsp; &nbsp; <span style="color: #006600; font-style: italic;">// note fillter for &nbsp;about:config is greasemonkey.scriptvals.http://www.FollowRank.com/</span><br />
&nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">typeof</span> maxDuration <span style="color: #339933;">!=</span> <span style="color: #3366CC;">&quot;number&quot;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; console.<span style="color: #660066;">error</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'maxDuration is NOT a number, but rather a '</span> <span style="color: #339933;">+</span> <span style="color: #000066; font-weight: bold;">typeof</span> maxDuration<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #3366CC;">&quot;&quot;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; <span style="color: #003366; font-weight: bold;">var</span> currentTime <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> Date<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #003366; font-weight: bold;">var</span> raw <span style="color: #339933;">=</span> GM_getValue<span style="color: #009900;">&#40;</span>key <span style="color: #339933;">+</span> <span style="color: #3366CC;">'_cacheDate'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">&quot;&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// get the age of the cache</span><br />
&nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>raw <span style="color: #339933;">!=</span> <span style="color: #3366CC;">&quot;&quot;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #003366; font-weight: bold;">var</span> cache_dt <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> Date<span style="color: #009900;">&#40;</span>parseInt<span style="color: #009900;">&#40;</span>raw<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #003366; font-weight: bold;">var</span> age <span style="color: #339933;">=</span> currentTime.<span style="color: #660066;">getTime</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">-</span> cache_dt.<span style="color: #660066;">getTime</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #003366; font-weight: bold;">var</span> allowed_age <span style="color: #339933;">=</span> maxDuration<span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>age <span style="color: #339933;">&lt;</span> <span style="color: #339933;">=</span> allowed_age<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #006600; font-style: italic;">// if the age is less than the max allowed age the get and return the cached value</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; GM_setCachedDataTrackingValueKey<span style="color: #009900;">&#40;</span>key<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">return</span> GM_getValue<span style="color: #009900;">&#40;</span>key<span style="color: #339933;">,</span> <span style="color: #3366CC;">&quot;&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">else</span> <span style="color: #009900;">&#123;</span><span style="color: #006600; font-style: italic;">// if the age is greater than the max then blank out the cache date and value and return black</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; GM_deleteValue<span style="color: #009900;">&#40;</span>key<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; GM_deleteValue<span style="color: #009900;">&#40;</span>key <span style="color: #339933;">+</span> <span style="color: #3366CC;">'_cacheDate'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; console.<span style="color: #660066;">info</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'GM cahaced data was too old so I killed it! Age was = '</span> <span style="color: #339933;">+</span> age <span style="color: #339933;">+</span> <span style="color: #3366CC;">' and allowed aged was ='</span> <span style="color: #339933;">+</span> allowed_age<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #3366CC;">&quot;&quot;</span><span style="color: #339933;">;</span><br />
<span style="color: #009900;">&#125;</span></div></td></tr></tbody></table></div>
<p>So there are several changes made to the code :<br />
In rereading the <a href="http://wiki.greasespot.net/Main_Page">Grease Monkey Wiki</a><a> I spotted the </a><a href="http://wiki.greasespot.net/GM_deleteValue">GM_deleteValue function</a> in it&#8217;s <a href="http://wiki.greasespot.net/Greasemonkey_Manual:API">api wiki</a>.    ack!!</p>
<p>I moved 2 variables (MaxCacheAge and  currentTime) outside the function themselves.  They could almost be constants, but as long as they are only calcualted once and not hard coded!  Also &#8220;currentTime&#8221; is stored in it&#8217;s milliseconds format since this is the only format I use it in. </p>
<p>I&#8217;ve included two utility functions : getIntersect (which returns an array with all elements in arr1 that are in arr2 as seen in a <a href="http://www.falsepositives.com/index.php/2009/12/01/javascript-function-to-get-the-intersect-of-2-arrays/">JavaScript Function to get the Intersect of 2 Arrays</a>)  and Array_diff (which returns an array with all elements in arr1 that are NOT in arr2)</p>
<p>The biggest change is the addition of 3 functions : GM_setCachedDataTrackingValueKey, GM_removeCachedDataTrackingValueKey and GM_flushCachedData which track the keys I have put in the Cache and ensure that nothing too old is ever stored there. I believe the first two are straight forward but it is flushCachedData that is more interesting / complicated. flushCachedData excepts a number which is the max age of all values in the cache which might be 48 hours (MaxCacheAge * 2) or 0 (Zero) in which case all values tracked in the cache are removed.  I can see some further optimizations for these functions, but they solve the basic problem of all that cached data always accumulating and never getting cleared away.</p>
<p>The basic usage remains the <a href="http://www.falsepositives.com/index.php/2009/12/09/use-greasemonkeys-persistent-data-functions-as-a-aged-cache/">same</a>.  The only thing I would add is that I have used it in the beginning of my GM script to do a cleanup<br />
</code></p>
<div class="codecolorer-container javascript default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br /></div></td><td><div class="javascript codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #003366; font-weight: bold;">var</span> TrackingDate <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">eval</span><span style="color: #009900;">&#40;</span>GM_getValue<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'CachedDataTracking_cacheDate'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">&quot;&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>TrackingDate <span style="color: #339933;">&lt;</span> <span style="color: #009900;">&#40;</span>currentTime <span style="color: #339933;">-</span> MaxCacheAge<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;GM_flushCachedData<span style="color: #009900;">&#40;</span>MaxCacheAge<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">//cleanup the cache by remove anything older than 24 hours&nbsp; &nbsp; </span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span></div></td></tr></tbody></table></div>
<p>If you wanted to blow away all the values stored by a GM script just include (once only!!) this:<br />
</code></p>
<div class="codecolorer-container javascript default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br /></div></td><td><div class="javascript codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #003366; font-weight: bold;">var</span> vals <span style="color: #339933;">=</span> GM_listValues<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">map</span><span style="color: #009900;">&#40;</span>GM_deleteValue<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></div></td></tr></tbody></table></div>
<p>Hope you find this useful.  cache away...</p>
<p>If you wish t see and use it in practice then check out <a href="http://userscripts.org/scripts/show/64286">Follow Rank and Follows in Common for Twitter User Profiles</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.falsepositives.com/index.php/2009/12/15/using-greasemonkey%e2%80%99s-persistent-data-functions-as-a-aged-cache-revised/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Use GreaseMonkey&#8217;s persistent data functions as a aged Cache.</title>
		<link>http://www.falsepositives.com/index.php/2009/12/09/use-greasemonkeys-persistent-data-functions-as-a-aged-cache/</link>
		<comments>http://www.falsepositives.com/index.php/2009/12/09/use-greasemonkeys-persistent-data-functions-as-a-aged-cache/#comments</comments>
		<pubDate>Wed, 09 Dec 2009 18:28:20 +0000</pubDate>
		<dc:creator>Ian</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[GreaseMonkey]]></category>
		<category><![CDATA[JavaScript]]></category>

		<guid isPermaLink="false">http://www.falsepositives.com/?p=2313</guid>
		<description><![CDATA[GreaseMonkey (Don&#8217;t know that GreaseMonkey  is the greatest thing since slice bread? See Greasemonkey) has two persistent data function&#8217;s, GM_setValue and GM_getValue, which let you set and get values. See Mark Pilgrams excellent Dive Into Greasemonkey : Storing and retrieving persistent data for more details.  (even better, go to GreaseSpot and it&#8217;s api [...]]]></description>
			<content:encoded><![CDATA[<p>GreaseMonkey (Don&#8217;t know that GreaseMonkey  is the greatest thing since slice bread? See <a href="http://en.wikipedia.org/wiki/Greasemonkey">Greasemonkey</a>) has two persistent data function&#8217;s, GM_setValue and GM_getValue, which let you set and get values. See Mark Pilgrams excellent <a href="http://diveintogreasemonkey.org/advanced/gm_getvalue.html">Dive Into Greasemonkey : Storing and retrieving persistent data</a> for more details.  (even better, go to <a href="http://www.greasespot.net/">GreaseSpot</a> and it&#8217;s <a href="http://wiki.greasespot.net/Greasemonkey_Manual:API">api wiki</a>).</p>
<p>UPDATE : <a href="http://www.falsepositives.com/index.php/2009/12/15/using-greasemonkey%E2%80%99s-persistent-data-functions-as-a-aged-cache-revised/">Revised</a></p>
<p>All well and good, but I wanted to store some data there (the results of a AJAX GET request), but didn&#8217;t want to store ithem forever just for a day or two or at least a couple of hours.</p>
<p>and so I &#8220;created&#8221; 2 functions, GM_setCachedDataValue and GM_getCachedDataValue, which allow use of the GM persistent data function&#8217;s as a aged Cache!  This allows me to &#8220;say&#8221; get me this value, unless it is older that X milliseconds old.</p>
<div class="codecolorer-container javascript default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br />26<br />27<br />28<br />29<br />30<br />31<br />32<br />33<br />34<br />35<br />36<br />37<br />38<br />39<br />40<br />41<br />42<br />43<br />44<br />45<br />46<br />47<br />48<br />49<br />50<br /></div></td><td><div class="javascript codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&nbsp; &nbsp; <span style="color: #006600; font-style: italic;">/**<br />
&nbsp; &nbsp; &nbsp;* GM_setCachedDataValue set the value, using the key name, and the cacheDate for the value based on the current datetime.<br />
&nbsp; &nbsp; &nbsp;* to see the values set use about:config in the firefox awsome bar and filter with greasemonkey.scriptvals.http://www.FollowRank.com/<br />
&nbsp; &nbsp; &nbsp;* @param {String} key &nbsp;The key argument is a string of no fixed format. &nbsp;Required. &nbsp;<br />
&nbsp; &nbsp; &nbsp;* @param {Object} value The value argument can be a string, boolean, or integer. Required.<br />
&nbsp; &nbsp; &nbsp;* @returns void<br />
&nbsp; &nbsp; &nbsp;* <br />
&nbsp; &nbsp; &nbsp;*/</span> <br />
&nbsp; &nbsp; <span style="color: #003366; font-weight: bold;">function</span> GM_setCachedDataValue<span style="color: #009900;">&#40;</span>key<span style="color: #339933;">,</span> value<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #006600; font-style: italic;">// key is the name of the value stored</span><br />
&nbsp; &nbsp; <span style="color: #006600; font-style: italic;">// value is the value to be stored</span><br />
&nbsp; &nbsp; <span style="color: #003366; font-weight: bold;">var</span> currentTime <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> Date<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">valueOf</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #003366; font-weight: bold;">var</span> raw <span style="color: #339933;">=</span> currentTime.<span style="color: #660066;">valueOf</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; GM_setValue<span style="color: #009900;">&#40;</span>key<span style="color: #339933;">,</span> value<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; GM_setValue<span style="color: #009900;">&#40;</span>key <span style="color: #339933;">+</span> <span style="color: #3366CC;">'_cacheDate'</span><span style="color: #339933;">,</span> raw.<span style="color: #660066;">toString</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #009900;">&#125;</span><br />
<br />
&nbsp; &nbsp; <span style="color: #006600; font-style: italic;">/**<br />
&nbsp; &nbsp; &nbsp;* GM_getCachedDataValue returns the value indicated by the key if a) it exists, b) if it is less the maxDuration milliseconds old; otherwise return a blank.<br />
&nbsp; &nbsp; &nbsp;* @param {String} key key is the name of the value stored. key argument is a string of no fixed format. &nbsp;Required.<br />
&nbsp; &nbsp; &nbsp;* @param {Number} maxDuration is the &nbsp;Maximum Duration (or how old) in milliseconds the cached data can be. maxDuration is a number. Required.<br />
&nbsp; &nbsp; &nbsp;* @returns a Integer, String or Boolean<br />
&nbsp; &nbsp; &nbsp;*/</span><br />
<span style="color: #003366; font-weight: bold;">function</span> GM_getCachedDataValue<span style="color: #009900;">&#40;</span>key<span style="color: #339933;">,</span> maxDuration<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #006600; font-style: italic;">// key is the name of the value stored</span><br />
&nbsp; &nbsp; <span style="color: #006600; font-style: italic;">// maxDuration is Maximum Duration (or how old) in milliseconds the cached data can be</span><br />
&nbsp; &nbsp; <span style="color: #006600; font-style: italic;">// note fillter for &nbsp;about:config is greasemonkey.scriptvals.http://www.FollowRank.com/</span><br />
&nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">typeof</span> maxDuration <span style="color: #339933;">!=</span> <span style="color: #3366CC;">&quot;number&quot;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; console.<span style="color: #660066;">error</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'maxDuration is NOT a number, but rather a '</span> <span style="color: #339933;">+</span> <span style="color: #000066; font-weight: bold;">typeof</span> maxDuration<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #3366CC;">&quot;&quot;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; <span style="color: #003366; font-weight: bold;">var</span> currentTime <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> Date<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #003366; font-weight: bold;">var</span> raw <span style="color: #339933;">=</span> GM_getValue<span style="color: #009900;">&#40;</span>key <span style="color: #339933;">+</span> <span style="color: #3366CC;">'_cacheDate'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">&quot;&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// get the age of the cache</span><br />
&nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>raw <span style="color: #339933;">!=</span> <span style="color: #3366CC;">&quot;&quot;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #003366; font-weight: bold;">var</span> cache_dt <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> Date<span style="color: #009900;">&#40;</span>parseInt<span style="color: #009900;">&#40;</span>raw<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #003366; font-weight: bold;">var</span> age <span style="color: #339933;">=</span> currentTime.<span style="color: #660066;">getTime</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">-</span> cache_dt.<span style="color: #660066;">getTime</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #003366; font-weight: bold;">var</span> allowed_age <span style="color: #339933;">=</span> maxDuration<span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>age <span style="color: #339933;">&lt;</span> <span style="color: #339933;">=</span> allowed_age<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #006600; font-style: italic;">// if the age is less than the max allowed age the get and return the cached value</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">return</span> GM_getValue<span style="color: #009900;">&#40;</span>key<span style="color: #339933;">,</span> <span style="color: #3366CC;">&quot;&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">else</span> <span style="color: #009900;">&#123;</span><span style="color: #006600; font-style: italic;">// if the age is greater than the max then blank out the cache date and value and return black</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; GM_setValue<span style="color: #009900;">&#40;</span>key<span style="color: #339933;">,</span> <span style="color: #3366CC;">&quot;&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; GM_setValue<span style="color: #009900;">&#40;</span>key <span style="color: #339933;">+</span> <span style="color: #3366CC;">'_cacheDate'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">&quot;&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; console.<span style="color: #660066;">info</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'GM cahaced data was too old so I killed it! Age was = '</span> <span style="color: #339933;">+</span> age <span style="color: #339933;">+</span> <span style="color: #3366CC;">' and allowed aged was ='</span> <span style="color: #339933;">+</span> allowed_age<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #3366CC;">&quot;&quot;</span><span style="color: #339933;">;</span><br />
<span style="color: #009900;">&#125;</span></div></td></tr></tbody></table></div>
<h4>How to use this :</h4>
<p>before doing my Ajax request I check my aged cahce to see if the value is there and is no older (in milliseconds) that a given age.  If it returns a non blank value that take that as the value and proceed, otherwise assume that it is either non there or a stale value, in either case that means I have to fetch fresh data which then needs to be stored.  Clear as mud?</p>
<p>here is a sample javascript code to show how to use it<br />
</code></p>
<div class="codecolorer-container javascript default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br /></div></td><td><div class="javascript codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #003366; font-weight: bold;">var</span> MaxCacheAge <span style="color: #339933;">=</span> <span style="color: #CC0000;">60</span> <span style="color: #339933;">*</span> <span style="color: #CC0000;">60</span> <span style="color: #339933;">*</span> <span style="color: #CC0000;">24</span> <span style="color: #339933;">*</span> <span style="color: #CC0000;">1000</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// Max Age for the Cached data is 1 day in milliseconds</span><br />
<span style="color: #003366; font-weight: bold;">var</span> tmp <span style="color: #339933;">=</span> GM_getCachedDataValue<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;LastRequest&quot;</span><span style="color: #339933;">,</span> MaxCacheAge<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>tmp <span style="color: #339933;">!=</span> <span style="color: #3366CC;">&quot;&quot;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; LastRequest <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">eval</span><span style="color: #009900;">&#40;</span>tmp<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #009900;">&#125;</span><br />
<span style="color: #000066; font-weight: bold;">else</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; GM_xmlhttpRequest<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; method<span style="color: #339933;">:</span> <span style="color: #3366CC;">'GET'</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; url<span style="color: #339933;">:</span> <span style="color: #3366CC;">'http://greaseblog.blogspot.com/atom.xml'</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066;">onload</span><span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>response<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; LastRequest <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">eval</span><span style="color: #009900;">&#40;</span>response.<span style="color: #660066;">responseText</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; GM_setCachedDataValue<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;LastRequest&quot;</span><span style="color: #339933;">,</span> response.<span style="color: #660066;">responseText</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp; <span style="color: #000066;">onerror</span><span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>response<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; LastRequest <span style="color: #339933;">=</span> <span style="color: #3366CC;">&quot;&quot;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; console.<span style="color: #660066;">error</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'ERROR'</span> <span style="color: #339933;">+</span> response.<span style="color: #000066;">status</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #009900;">&#125;</span></div></td></tr></tbody></table></div>
<p>This is generally faster than waiting for the calling service to return the get request, and if that service has a throttle limit (for Twitter it is 150 requests per hour limit, see <a href="http://apiwiki.twitter.com/Rate-limiting">Rate limiting</a>) it will (might) save you from hitting that too soon.</p>
<p>UPDATE : <a href="http://www.falsepositives.com/index.php/2009/12/15/using-greasemonkey%E2%80%99s-persistent-data-functions-as-a-aged-cache-revised/">Revised</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.falsepositives.com/index.php/2009/12/09/use-greasemonkeys-persistent-data-functions-as-a-aged-cache/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>JavaScript Function to get the Intersect of 2 Arrays</title>
		<link>http://www.falsepositives.com/index.php/2009/12/01/javascript-function-to-get-the-intersect-of-2-arrays/</link>
		<comments>http://www.falsepositives.com/index.php/2009/12/01/javascript-function-to-get-the-intersect-of-2-arrays/#comments</comments>
		<pubDate>Tue, 01 Dec 2009 19:46:54 +0000</pubDate>
		<dc:creator>Ian</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Web]]></category>

		<guid isPermaLink="false">http://www.falsepositives.com/?p=2275</guid>
		<description><![CDATA[In mathematics, the intersection (denoted as ∩) of two sets A and B is the set that contains all elements of A that also belong to B. 
I needed the javascript array equivalent, so that given an array A = ["a","b","c", "d"] and B = ["b", "d", "e"], getIntersect(A, B) = ["b", "d"]
123456789101112function getIntersect&#40;arr1, arr2&#41; [...]]]></description>
			<content:encoded><![CDATA[<p>In mathematics, the <a href="http://en.wikipedia.org/wiki/Intersection_%28set_theory%29" rel="tag">intersection </a>(denoted as ∩) of two sets A and B is the set that contains all elements of A that also belong to B. </p>
<p>I needed the javascript array equivalent, so that given an array A = ["a","b","c", "d"] and B = ["b", "d", "e"], getIntersect(A, B) = ["b", "d"]</p>
<div class="codecolorer-container javascript default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br /></div></td><td><div class="javascript codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #003366; font-weight: bold;">function</span> getIntersect<span style="color: #009900;">&#40;</span>arr1<span style="color: #339933;">,</span> arr2<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #003366; font-weight: bold;">var</span> temp <span style="color: #339933;">=</span> <span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">for</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">var</span> i <span style="color: #339933;">=</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">;</span> i <span style="color: #339933;">&lt;</span> arr1.<span style="color: #660066;">length</span><span style="color: #339933;">;</span> i<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">for</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">var</span> k <span style="color: #339933;">=</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">;</span> k <span style="color: #339933;">&lt;</span> arr2.<span style="color: #660066;">length</span><span style="color: #339933;">;</span> k<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span>arr1<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span> <span style="color: #339933;">==</span> arr2<span style="color: #009900;">&#91;</span>k<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; temp.<span style="color: #660066;">push</span><span style="color: #009900;">&#40;</span> arr1<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">break</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">return</span> temp<span style="color: #339933;">;</span><br />
<span style="color: #009900;">&#125;</span></div></td></tr></tbody></table></div>
<h3>Update:</h3>
<p> In the comments, Jeffery suggests a version using a javascript hash table (also called an associative array or a map), which would be much faster especially if arr2 was much shorter than arr1.  I will do some benchmarking with some live data (from the app I extracted this from) to see how badly my version does. (See below : he sunk me big time! use his version.)<br />
</code></p>
<div class="codecolorer-container javascript default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br /></div></td><td><div class="javascript codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #003366; font-weight: bold;">function</span> getIntersect<span style="color: #009900;">&#40;</span>arr1<span style="color: #339933;">,</span> arr2<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #003366; font-weight: bold;">var</span> r <span style="color: #339933;">=</span> <span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> o <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span><span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span> l <span style="color: #339933;">=</span> arr2.<span style="color: #660066;">length</span><span style="color: #339933;">,</span> i<span style="color: #339933;">,</span> v<span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span>i <span style="color: #339933;">=</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">;</span> i <span style="color: #339933;">&lt;</span> l<span style="color: #339933;">;</span> i<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; o<span style="color: #009900;">&#91;</span>arr2<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">true</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; l <span style="color: #339933;">=</span> arr1.<span style="color: #660066;">length</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span>i <span style="color: #339933;">=</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">;</span> i <span style="color: #339933;">&lt;</span> l<span style="color: #339933;">;</span> i<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; v <span style="color: #339933;">=</span> arr1<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>v <span style="color: #000066; font-weight: bold;">in</span> o<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; r.<span style="color: #660066;">push</span><span style="color: #009900;">&#40;</span>v<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">return</span> r<span style="color: #339933;">;</span><br />
<span style="color: #009900;">&#125;</span></div></td></tr></tbody></table></div>
<p><strike>He is also too kind to point out one inefficient / bad practice in the code above : that I should have stored the lengths of the arrays in a variable, rather than recalculating it again and again. </strike>  Nevermind ...</p>
<p>And elsewhere, Pete pointed out the <a href="http://documentcloud.github.com/underscore/">Underscore</a>, a utility-belt library for JavaScript that provides a lot of the functional programming support, and its _.intersect function .</p>
<h3>Further update:</h3>
<p> Now with benchmark results and less smoke up my ass!  (repeat after me : "test your assumptions before making an ass of yourself (again)", now repeat 100 times).</p>
<p>I created the (very) simple benchmarking file that would actual work, a html file with embedded javascript with has the 2 functions for testing and 2 arrays : one with elements 4646 and one with  1103 elements.</p>
<p>The file is <a href="http://www.falsepositives.com/files/test_array_interect_file.html">http://www.falsepositives.com/files/test_array_interect_file.html</a>. There is also a <a href="http://www.falsepositives.com/files/test_array_interect_file2.html">version</a> which iterates the test 100 tests, and shows the average result in a table as below.</p>
<p>I also rewrote the test from using firefox's console.log and console.time functions to using document.write and some raw javascript to log the time it took for a given function to run so I could run this in different browsers. (more about this later)</p>
<p>So the raw results where that Jeffery's version blew my version out of the water!  in FF 3.3 mine ran ~ 85 to 90 ms and his ~1 to 2 ms !!  So creating the hash and searching it are really really optimized. </p>
<p>The second surprise was that my suggested optimization of my version ("storing the lengths of the arrays in a variable") added several ms of run time! I think this is because a) the lengths are already calculated and stored as  a property of each array, and b) their is some overhead of storing the 2 length values as local variables.  Since object properties are really hashs, and we have just learned that hashs are really really fast the result make some sense.  Storing a value instead of recalculating it is still a "really good idea", just not this time.</p>
<p>Having rewritten the test in more browser generic fashion here are the results for different browsers (times are in milliseconds) :</p>
<table border="1">
<thead>
<tr>
<th></th>
<th>getIntersect of a1 , a2</th>
<th>getIntersect of a2 , a1</th>
<th>getIntersect JT of a1 , a2 </th>
<th>getIntersect JT of a2 , a1 </th>
</tr>
</thead>
<tbody>
<tr>
<td>FireFox 3.5.5</td>
<td style="text-align: right;">89.27</td>
<td style="text-align: right;">74.52</td>
<td style="text-align: right;">1.19</td>
<td style="text-align: right;">1.44</td>
</tr>
<tr>
<td>Safari 4.0.3</td>
<td style="text-align: right;">52.32</td>
<td style="text-align: right;">43.60</td>
<td style="text-align: right;">3.11</td>
<td style="text-align: right;">2.97</td>
</tr>
<tr>
<td>Safari on iPdod Touch (3.1.2)</td>
<td style="text-align: right;">2049.00</td>
<td style="text-align: right;">1712.00</td>
<td style="text-align: right;">48.00</td>
<td style="text-align: right;">39.00</td>
</tr>
<tr>
<td>Chrome 4.0.223</td>
<td style="text-align: right;">63.91</td>
<td style="text-align: right;">53.00</td>
<td style="text-align: right;">0.82</td>
<td style="text-align: right;">1.45</td>
</tr>
<tr>
<td>IE 7.0.5730</td>
<td style="text-align: right;">3656.00</td>
<td style="text-align: right;">3068.60</td>
<td style="text-align: right;">9.60</td>
<td style="text-align: right;">9.40</td>
</tr>
<tr>
<td></td>
<td style="text-align: right;"></td>
<td style="text-align: right;"></td>
<td style="text-align: right;"></td>
<td style="text-align: right;"></td>
</tr>
</tbody>
</table>
<p>Your mileage will vary.  The  absolute number are not as interesting as the relative values.</p>
<p>I have also run my test against <a href="http://documentcloud.github.com/underscore/">Underscore</a>, and its _.intersect function for some interesting results:</p>
<table style="width: 182px;" border="1">
<tbody>
<tr>
<td>FireFox</td>
<td style="text-align: right;">232.75</td>
</tr>
<tr>
<td>Safari </td>
<td style="text-align: right;">137.22</td>
</tr>
<tr>
<td>Chrome </td>
<td style="text-align: right;"> 42.26</td>
</tr>
<tr>
<td>IE </td>
<td style="text-align: right;"> 1953</td>
</tr>
<tr>
<td></td>
<td style="text-align: right;"></td>
</tr>
</tbody>
</table>
<p>So not as fast as even my humble version, but keep in mind that the Underscore _.intersect function handls any number of arrays to intersect, and has 50 additional utility functions.</p>
<p>So what can we learn from this? </p>
<p>Hashes are very fast; Jeffery is smart; IE stinks; Ian needs to test his ASSumptions!</code></p>
]]></content:encoded>
			<wfw:commentRss>http://www.falsepositives.com/index.php/2009/12/01/javascript-function-to-get-the-intersect-of-2-arrays/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
