Date.now = Date.now || function() { return new Date().getTime(); }; /* ### jQuery XML to JSON Plugin v1.1 - 2008-07-01 ### * http://www.fyneworks.com/ - diego@fyneworks.com * Dual licensed under the MIT and GPL licenses: * http://www.opensource.org/licenses/mit-license.php * http://www.gnu.org/licenses/gpl.html ### Website: http://www.fyneworks.com/jquery/xml-to-json/ *//* # INSPIRED BY: http://www.terracoder.com/ AND: http://www.thomasfrank.se/xml_to_json.html AND: http://www.kawa.net/works/js/xml/objtree-e.html *//* This simple script converts XML (document of code) into a JSON object. It is the combination of 2 'xml to json' great parsers (see below) which allows for both 'simple' and 'extended' parsing modes. */ // Avoid collisions ;if(window.jQuery) (function($){ // Add function to jQuery namespace $.extend({ // converts xml documents and xml text to json object xml2json: function(xml, extended) { if(!xml) return {}; // quick fail //### PARSER LIBRARY // Core function function parseXML(node, simple){ if(!node) return null; var txt = '', obj = null, att = null; var nt = node.nodeType, nn = jsVar(node.localName || node.nodeName); var nv = node.text || node.nodeValue || ''; /*DBG*/ //if(window.console) console.log(['x2j',nn,nt,nv.length+' bytes']); if(node.childNodes){ if(node.childNodes.length>0){ /*DBG*/ //if(window.console) console.log(['x2j',nn,'CHILDREN',node.childNodes]); $.each(node.childNodes, function(n,cn){ var cnt = cn.nodeType, cnn = jsVar(cn.localName || cn.nodeName); var cnv = cn.text || cn.nodeValue || ''; /*DBG*/ //if(window.console) console.log(['x2j',nn,'node>a',cnn,cnt,cnv]); if(cnt == 8){ /*DBG*/ //if(window.console) console.log(['x2j',nn,'node>b',cnn,'COMMENT (ignore)']); return; // ignore comment node } else if(cnt == 3 || cnt == 4 || !cnn){ // ignore white-space in between tags if(cnv.match(/^\s+$/)){ /*DBG*/ //if(window.console) console.log(['x2j',nn,'node>c',cnn,'WHITE-SPACE (ignore)']); return; }; /*DBG*/ //if(window.console) console.log(['x2j',nn,'node>d',cnn,'TEXT']); txt += cnv.replace(/^\s+/,'').replace(/\s+$/,''); // make sure we ditch trailing spaces from markup } else{ /*DBG*/ //if(window.console) console.log(['x2j',nn,'node>e',cnn,'OBJECT']); obj = obj || {}; if(obj[cnn]){ /*DBG*/ //if(window.console) console.log(['x2j',nn,'node>f',cnn,'ARRAY']); // http://forum.jquery.com/topic/jquery-jquery-xml2json-problems-when-siblings-of-the-same-tagname-only-have-a-textnode-as-a-child if(!obj[cnn].length) obj[cnn] = myArr(obj[cnn]); obj[cnn] = myArr(obj[cnn]); obj[cnn][ obj[cnn].length ] = parseXML(cn, true/* simple */); obj[cnn].length = obj[cnn].length; } else{ /*DBG*/ //if(window.console) console.log(['x2j',nn,'node>g',cnn,'dig deeper...']); obj[cnn] = parseXML(cn); }; }; }); };//node.childNodes.length>0 };//node.childNodes if(node.attributes){ if(node.attributes.length>0){ /*DBG*/ //if(window.console) console.log(['x2j',nn,'ATTRIBUTES',node.attributes]) att = {}; obj = obj || {}; $.each(node.attributes, function(a,at){ var atn = jsVar(at.name), atv = at.value; att[atn] = atv; if(obj[atn]){ /*DBG*/ //if(window.console) console.log(['x2j',nn,'attr>',atn,'ARRAY']); // http://forum.jquery.com/topic/jquery-jquery-xml2json-problems-when-siblings-of-the-same-tagname-only-have-a-textnode-as-a-child //if(!obj[atn].length) obj[atn] = myArr(obj[atn]);//[ obj[ atn ] ]; obj[cnn] = myArr(obj[cnn]); obj[atn][ obj[atn].length ] = atv; obj[atn].length = obj[atn].length; } else{ /*DBG*/ //if(window.console) console.log(['x2j',nn,'attr>',atn,'TEXT']); obj[atn] = atv; }; }); //obj['attributes'] = att; };//node.attributes.length>0 };//node.attributes if(obj){ obj = $.extend( (txt!='' ? new String(txt) : {}),/* {text:txt},*/ obj || {}/*, att || {}*/); txt = (obj.text) ? (typeof(obj.text)=='object' ? obj.text : [obj.text || '']).concat([txt]) : txt; if(txt) obj.text = txt; txt = ''; }; var out = obj || txt; //console.log([extended, simple, out]); if(extended){ if(txt) out = {};//new String(out); txt = out.text || txt || ''; if(txt) out.text = txt; if(!simple) out = myArr(out); }; return out; };// parseXML // Core Function End // Utility functions var jsVar = function(s){ return String(s || '').replace(/-/g,"_"); }; // NEW isNum function: 01/09/2010 // Thanks to Emile Grau, GigaTecnologies S.L., www.gigatransfer.com, www.mygigamail.com function isNum(s){ // based on utility function isNum from xml2json plugin (http://www.fyneworks.com/ - diego@fyneworks.com) // few bugs corrected from original function : // - syntax error : regexp.test(string) instead of string.test(reg) // - regexp modified to accept comma as decimal mark (latin syntax : 25,24 ) // - regexp modified to reject if no number before decimal mark : ".7" is not accepted // - string is "trimmed", allowing to accept space at the beginning and end of string var regexp=/^((-)?([0-9]+)(([\.\,]{0,1})([0-9]+))?$)/ return (typeof s == "number") || regexp.test(String((s && typeof s == "string") ? jQuery.trim(s) : '')); }; // OLD isNum function: (for reference only) //var isNum = function(s){ return (typeof s == "number") || String((s && typeof s == "string") ? s : '').test(/^((-)?([0-9]*)((\.{0,1})([0-9]+))?$)/); }; var myArr = function(o){ // http://forum.jquery.com/topic/jquery-jquery-xml2json-problems-when-siblings-of-the-same-tagname-only-have-a-textnode-as-a-child //if(!o.length) o = [ o ]; o.length=o.length; if(!$.isArray(o)) o = [ o ]; o.length=o.length; // here is where you can attach additional functionality, such as searching and sorting... return o; }; // Utility functions End //### PARSER LIBRARY END // Convert plain text to xml if(typeof xml=='string') xml = $.text2xml(xml); // Quick fail if not xml (or if this is a node) if(!xml.nodeType) return; if(xml.nodeType == 3 || xml.nodeType == 4) return xml.nodeValue; // Find xml root node var root = (xml.nodeType == 9) ? xml.documentElement : xml; // Convert xml to json var out = parseXML(root, true /* simple */); // Clean-up memory xml = null; root = null; // Send output return out; }, // Convert text to XML DOM text2xml: function(str) { // NOTE: I'd like to use jQuery for this, but jQuery makes all tags uppercase //return $(xml)[0]; var out; try{ var xml = ($.browser.msie)?new ActiveXObject("Microsoft.XMLDOM"):new DOMParser(); xml.async = false; }catch(e){ throw new Error("XML Parser could not be instantiated") }; try{ if($.browser.msie) out = (xml.loadXML(str))?xml:false; else out = xml.parseFromString(str, "text/xml"); }catch(e){ throw new Error("Error parsing XML string") }; return out; } }); // extend $ })(jQuery); var CN = CN || {}; CN.style = CN.style || {}; CN.style.feeds = (function($) { var MIN_POLL_INTERVAL = 60e3; var cache = {}, pollers = {}; return { loadFeed: function(feed, callback) { var uri = feed["uri"]; if (Boolean(feed["interval"])) { var interval = feed["interval"]; pollers[uri] = Math.min( Math.max(MIN_POLL_INTERVAL, interval), (isNaN(pollers[uri])) ? Infinity : pollers[uri] ); load(function(json, feed) { callback(json, feed); setInterval(function() { load(callback); }, interval); }); } else { load(callback); } function load(callback) { var cachedFeed = cache[uri]; if (Boolean(cachedFeed) && Date.now() - cachedFeed["timestamp"] < MIN_POLL_INTERVAL) { return notify(cachedFeed["feed"], callback); } var crossOrigin = false; if (typeof feed["cross-origin"] !== "undefined") { crossOrigin = feed["cross-origin"]; } else if (/^([a-z]+:)?(\/\/)/i.test(uri)) { crossOrigin = true; } try { (crossOrigin) ? proxied(callback) : direct(callback); } catch (e) { feedError(e); } } function proxied(callback) { var url = null; var protocol = /^([a-z]+:)?\/\//i.exec(uri); if (Boolean(protocol)) { if (Boolean(protocol[1])) url = uri; else url = "http:" + uri; } else { url = "http://www.style.com" + uri; } var o = new google.feeds.Feed(url); o.setNumEntries(10); o.includeHistoricalEntries(); o.setResultFormat(google.feeds.Feed.XML_FORMAT); o.load(function(result) { if (typeof result["error"] !== "undefined") feedError(); loaded(result.xmlDocument, callback); }); } function direct(callback) { $.ajax({ url: uri, dataType: "xml", timeout: MIN_POLL_INTERVAL, success: function(xml) { if (typeof xml["parsererror"] !== "undefined") { proxied(callback); } else { loaded(xml, callback); } }, error: function() { proxied(callback); } }); } function loaded(xml, callback) { var json = $.xml2json(xml); cache[uri] = { "timestamp": Date.now(), "feed": json }; if (Modernizr && Modernizr.localstorage) localStorage.setItem("CN.style.feeds", JSON.stringify(cache)); notify(json, callback); } function notify(json, callback) { callback(json, feed); } function feedError(e) { } } }; }(jQuery)); Date.prototype.toOffsetString = (function($) { return function(options) { var settings = $.extend({ "maxHours" : 24, "minHours" : 1, "minMinutes" : 1, "minSeconds" : 1 }, options || { }); var timeDiff = new Date().getTime() - this.getTime(); // If more than settings["maxHours"] hours have elapsed, the time is formatted like "Jan 1, 12:01 AM" if (timeDiff > settings["maxHours"] * 60 * 60e3) { // CN.date.format() is broken; it formats midnight as "00" instead of "12" when using "h" in the format string // return CN.date.format(this, "MMM d, hh:mm a"); var intMonth = this.getMonth(); var intDate = this.getDate(); var intHour = this.getHours(); var intMinutes = this.getMinutes(); var month = CN.date.getMonthName(this.getMonth(), { form: "short" }); var date = String(intDate); var hour = String((intHour > 12) ? intHour - 12 : (intHour || 12)); var minutes = CN.utils.padLeft(String(intMinutes), 2, "0"); var period = (intHour > 12) ? "pm" : "am"; return month + " " + date + ", " + hour + ":" + minutes + " " + period; } // if more than settings["minHours"] has elapsed since the item was published, the time is formatted like "6 hours ago" else if (timeDiff >= settings["minHours"] * 60 * 60e3) { var hoursDiff = parseInt(timeDiff / (60 * 60e3)); return ("" + hoursDiff + " hour" + (hoursDiff > 1 ? "s " : " ") + "ago"); } // if more than settings["minMinutes"] has elapsed since the item was published, the time is formatted like "12 minutes ago" else if (timeDiff >= settings["minMinutes"] * 60e3) { var minsDiff = parseInt(timeDiff / (60e3)); return ("" + minsDiff + " minute" + (minsDiff > 1 ? "s " : " ") + "ago"); } // if more than settings["minSeconds"] has elapsed since the item was published, the time is formatted like "42 seconds ago" else if (timeDiff >= settings["minSeconds"] * 1e3) { var secsDiff = parseInt(timeDiff / 1e3); return ("" + secsDiff + " second" + (secsDiff > 1 ? "s " : " ") + "ago"); } // if the publication time of the item is less than settings["minSeconds"], or some point in the future, the time is formatted as "just now" else { return "just now"; } }; }(jQuery)); (function($) { var container$; var feeds = [ { "link": "/stylefile", "title": "style file", "uri": "/stylefile/feed/rss2", "interval": 60e3 }, { "link": "/beauty/beautycounter", "title": "beauty counter", "uri": "/beauty/beautycounter/feed/rss2", "interval": 60e3 }, { "link": "//nowmanifest.com", "title": "now manifest", "uri": "//nowmanifest.com/multifeed", "cross-origin": true, "include-author": true, "interval": 60e3 } ]; $(function() { container$ = $("#feeds > .container"); var cache = []; var nav$ = $(""); var navList$ = $("