Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Slash.ArticleInfo: store (in a universal format) article-related data…
… needed by client code This builds on the work pudge and I did for sfnet. 'Article', here, is a general name for an entry in the main list of the page, e.g., a firehose entry, or the story in editStory, etc. Uses only valid HTML. You hang your sd-info-block directly from the element that represents the article, e.g., <div id="firehose-1128650" class="briefarticle adminmode" ... > <span class="sd-info-block"> <span class="sd-key-firehose-id">1128650</span> <span class="type">firehose</span> <span class="new-article">true</span> </span> ... </div> $('#firehose-1128650').article_info('type') => 'firehose' $('#firehose-1128650').article_info('init-time', new Date()); If you can't hang it right from the article element, provide a 'scope' definition: <span class="sd-info-block"> <span class="sd-key-firehose-id">1128650</span> <span class="scope">#firehose-1128650</span> <span class="type">firehose</span> </span> Given any element that is or is within an article that has an sd-info-block $(elem).article_info__find_articles() finds that outer article-element.
- Loading branch information
Showing
2 changed files
with
223 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,137 @@ | ||
;(function($){ | ||
|
||
Slash.Util.Package({ named: 'Slash.ArticleInfo', | ||
stem_function: datum, | ||
api: { | ||
key: find_key, | ||
find_article: elem_fn($find_articles), | ||
find: elem_fn($find_info_blocks) | ||
}, | ||
jquery: { | ||
stem_function: function( k, v ){ | ||
if ( v === undefined ) { | ||
return datum(this[0], k); | ||
} | ||
return this.each(function(){ | ||
datum(this, k, v); | ||
}); | ||
}, | ||
element_api: { | ||
key: function(){ | ||
return find_key(this[0]); | ||
}, | ||
get: function( k ){ | ||
return datum(this[0], k); | ||
}, | ||
set: function( k, v ){ | ||
return this.each(function(){ | ||
datum(this, k, v); | ||
}); | ||
}, | ||
find_articles: jquery_fn($find_articles), | ||
find: jquery_fn($find_info_blocks) | ||
} | ||
} | ||
}); | ||
|
||
var re_key = /^sd-key-(.*)/; | ||
var select_keys = '[class^=sd-key-]'; | ||
var select_first_key = select_keys + ':first'; | ||
var select_info_blocks = 'span.sd-info-block'; | ||
var info_block_html = '<span class="sd-info-block" style="display: none" />'; | ||
|
||
function datum( elem, k, v ){ | ||
var info = Slash.ArticleInfo.find(elem), | ||
$info = info ? $(info) : $([]), | ||
$datum = $info.find('.' + k); | ||
|
||
if ( v === undefined ) { | ||
return $datum.text(); | ||
} | ||
if ( ! $datum.length ) { | ||
if ( ! $info.length ) { | ||
var $elem = $(elem), | ||
$key = $elem.find(select_first_key).siblings(select_keys).andSelf(); | ||
if ( $key.length ) { | ||
$key.wrapAll(info_block_html); | ||
} else { | ||
$elem.prepend(info_block_html); | ||
} | ||
$info = $elem.find(select_info_blocks); | ||
} | ||
$datum = $info.append('<span class="' + k + '" />').find('.' + k); | ||
} | ||
$datum.text(v); | ||
} | ||
|
||
function find_key( elem ){ | ||
var $key = $(elem).find(select_first_key); | ||
if ( $key.length ) { | ||
return { | ||
key: $key.text(), | ||
key_type: re_key.exec($key[0].className)[1] | ||
}; | ||
} | ||
} | ||
|
||
function $find_info_blocks( $list ){ | ||
return $list.map(function(){ | ||
var $this = $(this); | ||
if ( $this.is(select_info_blocks) ) { | ||
return this; | ||
} | ||
var $children = $this.find(select_info_blocks); | ||
if ( $children.length ) { | ||
return $children.get(); | ||
} | ||
return $this.nearest_parent(select_info_blocks).get(); | ||
}); | ||
} | ||
|
||
function $find_articles( $list ){ | ||
return $find_info_blocks($list).map(function(){ | ||
var $this = $(this); | ||
return $this.nearest_parent($this.find('span.scope').text() || 'div')[0]; | ||
}); | ||
} | ||
|
||
function jquery_fn( fn ){ | ||
return function( expr ){ | ||
var $list = fn(this); | ||
if ( expr !== undefined ) { | ||
$list = $list.filter(expr); | ||
} | ||
return this.pushStack($.unique($list)); | ||
}; | ||
} | ||
|
||
function elem_fn( fn ){ | ||
return function( elem ){ | ||
var $list = fn($(elem)); | ||
if ( $list.length ) { | ||
return $list[0]; | ||
} | ||
} | ||
} | ||
|
||
})(Slash.jQuery); | ||
|
||
/* | ||
$('#firehoselist .tagui-need-init'). | ||
article_info__find_articles(); | ||
<span class="sd-info-block"> | ||
<span class="sd-key-firehose-id">1128650</span> | ||
<span class="scope">#firehose-1128650</span> | ||
<span class="type">firehose</span> | ||
<span class="tagui-needs-init">true</span> | ||
</span> | ||
<span class="sd-info-block"> | ||
<span class="sd-key-url">http://cmdrtaco.net</span> | ||
<span class="type">project</span> | ||
</span> | ||
*/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
<html> | ||
<head> | ||
<title>Unit Tests: slash.article-info.js</title> | ||
|
||
<script src="../jquery/jquery-1.2.6.js" type="text/javascript"></script> | ||
<link href="http://dev.jquery.com/view/trunk/qunit/testsuite.css" rel="stylesheet" type="text/css" media="screen"> | ||
<script src="http://dev.jquery.com/view/trunk/qunit/testrunner.js" type="text/javascript"></script> | ||
|
||
<script src="../slash.util.js" type="text/javascript"></script> | ||
<script src="../slash.article-info.js" type="text/javascript"></script> | ||
|
||
<script type="text/javascript"> | ||
(function($){ | ||
|
||
$(function(){ | ||
|
||
function not_ok( m ){ | ||
ok(false, m); | ||
} | ||
|
||
module('slash.article-info.js'); | ||
|
||
test('api basics', function(){ | ||
ok(Slash, 'Slash name-space exists'); | ||
ok(Slash.ArticleInfo, 'Slash.ArticleInfo exists'); | ||
ok($.isFunction(Slash.ArticleInfo), '...and it\'s a function'); | ||
ok($.fn.article_info, 'exists on jQuery prototype, too'); | ||
ok($.isFunction($.fn.article_info), '...and it\'s a function'); | ||
|
||
var $articles = $('#main').article_info__find_articles(); | ||
ok(true, 'survived a call $.fn.article_info__find_articles()'); | ||
equals($articles.length, 4, 'and it returned the right number of articles'); | ||
}); | ||
|
||
|
||
test('regressions', function(){ | ||
}); | ||
|
||
|
||
|
||
|
||
|
||
}); | ||
|
||
})(jQuery); | ||
</script> | ||
|
||
<style type="text/css"> | ||
[class^=sd-key-] { display: none } | ||
</style> | ||
|
||
</head> | ||
<body> | ||
<h1>Unit Tests: api.js</h1> | ||
<h2 id="banner"></h2> | ||
<h2 id="userAgent"></h2> | ||
<ol id="tests"></ol> | ||
<div id="main"> | ||
<div id='fish' class='fish'> | ||
<span class="sd-info-block" style="display: none"></span> | ||
</div> | ||
<div id='dog' class='dog'> | ||
<span class="sd-info-block" style="display: none"></span> | ||
</div> | ||
<div id='cat' class='cat'> | ||
<span class="sd-info-block" style="display: none"></span> | ||
</div> | ||
<div id='car'> | ||
<span class="sd-key-floozberry-flop">jmMoxqRz+8</span> | ||
<span class="sd-key-url">jmMoxqRz+8</span> | ||
<div> | ||
<span class="sd-key-firehose-id">388</span> | ||
</div> | ||
</div> | ||
<div id='boat'> | ||
<div> | ||
<div> | ||
<span class="sd-info-block" style="display: none"> | ||
<span class="scope">#boat</span> | ||
</span> | ||
</div> | ||
</div> | ||
</div> | ||
</div> | ||
</body> | ||
</html> |