mozilla

Revision 509271 of Template:MDN:Common

  • Revision slug: Template:mdn:common
  • Revision title: Template:MDN:Common
  • Revision id: 509271
  • Created:
  • Creator: lorchard_mozilla
  • Is current revision? No
  • Comment

Revision Content

<% var MDN = module.exports = { link: function (url, text, title) { var e = MDN.htmlEscapeArgs(['url', 'text', 'title'], arguments); return [ '', e.text, '' ].join(''); }, htmlEscapeArgs: function (names, args) { var e = {}; names.forEach(function (name, idx) { e[name] = kuma.htmlEscape(args[idx]); }); return e; }, /** * Given a set of strings like this: * { "en-US": "Foo", "de": "Bar", "es": "Baz" } * Return the one which matches the current locale. */ localString: function (strings) { var lang = env.locale; if (!(lang in strings)) lang = 'en-US'; return strings[lang]; }, /** * Given a string, escapes all quotes within it. */ escapeQuotes: function(a) { var b = ""; for (var i = 0, len = a.length; i < len; i++) { var c = a[i]; if (c=="\"") c = """; b += c; } return b.replace(/(<([^>]+)>)/ig, ""); }, /** * Accepts a relative URL or an attachment object * Returns the content of a given file. */ getFileContent: function(fileObjOrUrl) { var url = fileObjOrUrl.url || fileObjOrUrl; if(!url) return ''; var result = '', base_url = ''; // New file urls include attachment host, so we don't need to prepend it var fUrl = kuma.url.parse(url); if (!fUrl.host) { var p = kuma.url.parse(env.url, true), base_url = p.protocol + '//' + p.host; } url = base_url + url; return cacheFn('kuma:get_attachment_content:' + md5(url.toLowerCase()), 3600, function(next) { try { request({ method: 'GET', headers: { 'Cache-Control': env.cache_control }, url: url }, function(err, resp, body) { if(resp && 200 == resp.statusCode) { next(body); } else if(err) { next(null); } }); } catch(e) { next("error: " + e); } }); }, /** * #### cacheFnIgnoreCacheControl * Cache a function, and use cached results no matter what * Cache-Control we get from a shift-refresh. */ cacheFnIgnoreCacheControl: function (key, tm_out, to_cache) { var result = null, err_result = null, f = new Future(), mc = memcached; mc.get(key, function (err, c_result) { if (c_result) { result = c_result; f['return'](); } else { try { to_cache(function (val) { mc.set(key, val, tm_out, function (err, c_result) { result = val; f['return'](); }); }); } catch (e) { err_result = e; result = ''; f['return'](); } } }); f.wait(); if (err_result) { throw err_result; } return result; }, // #### memcacheSet(key, value, timeout) // // Store a value in memcache with the given key and timeout (in seconds) memcacheSet: function (key, value, tmout) { var result = null, err_result = null, f = new Future(), mc = memcached; mc.set(key, value, tmout, function (err, c_result) { err_result = err; result = c_result; f['return'](); }); f.wait(); if (err_result) { throw err_result; } return result; }, // #### memcacheGet(key) // // Fetch the value for a key from memcache memcacheGet: function (key) { var result = null, err_result = null, f = new Future(), mc = memcached; mc.get(key, function (err, c_result) { err_result = err; result = c_result; f['return'](); }); f.wait(); if (err_result) { throw err_result; } return result; }, // #### defaults(object, *defaults) // // Fill in undefined properties in object with values from the defaults // objects, and return the object. As soon as the property is filled, // further defaults will have no effect. // // Stolen from http://underscorejs.org/#defaults defaults: function (obj) { Array.prototype.slice.call(arguments, 1).forEach(function(source) { if (source) { for (var prop in source) { if (obj[prop] === void 0) obj[prop] = source[prop]; } } }); return obj; }, // #### fetchJSONResource // Fetch an HTTP resource with JSON representation, parse the JSON and // return a JS object. fetchJSONResource: function (url, opts) { opts = MDN.defaults(opts || {}, { headers: { 'Cache-Control': env.cache_control, 'Accept': 'application/json', 'Content-Type': 'application/json' }, }); return JSON.parse(MDN.fetchHTTPResource(url, opts)); }, // #### fetchHTTPResource // Fetch an HTTP resource, return the response body. fetchHTTPResource: function (url, opts) { opts = MDN.defaults(opts || {}, { method: 'GET', headers: { 'Cache-Control': env.cache_control, 'Accept': "text/plain", 'Content-Type': "text/plain" }, url: url, cache_key: 'kuma:http_resource:' + md5(url.toLowerCase()), cache_timeout: 3600, ignore_cache_control: false }); var to_cache = function (next) { try { var req = request.get(opts); req.on('response', function(res) { var chunks = []; var content_length = 0; res.on('error', function(chunk) { next(null); }); res.on('data', function(chunk) { chunks.push(chunk); content_length += chunk.length; }); res.on('end', function() { var buffer = new Buffer(content_length); var offset = 0; for (var i=0; i

Revision Source

<% var MDN = module.exports = {
    
    link: function (url, text, title) {
        var e = MDN.htmlEscapeArgs(['url', 'text', 'title'], arguments);
        return [
            '<a href="',
            e.url,
            '" title="',
            e.title,
            '">',
            e.text,
            '</a>'
        ].join('');
    },
    
    htmlEscapeArgs: function (names, args) {
        var e = {};
        names.forEach(function (name, idx) {
            e[name] = kuma.htmlEscape(args[idx]);
        });
        return e;
    },
    
    /**
     * Given a set of strings like this:
     *     { "en-US": "Foo", "de": "Bar", "es": "Baz" }
     * Return the one which matches the current locale.
     */
    localString: function (strings) {
        var lang = env.locale;
        if (!(lang in strings)) lang = 'en-US';
        return strings[lang];
    },
    
    /**
     * Given a string, escapes all quotes within it.
     */
    escapeQuotes: function(a) {
        var b = "";
        for (var i = 0, len = a.length; i < len; i++) {
            var c = a[i];
            if (c=="\"") c = "&quot;";
            b += c;
        }
        return b.replace(/(<([^>]+)>)/ig, "");
    },

    /**
     * Accepts a relative URL or an attachment object
     * Returns the content of a given file.
     */
    getFileContent: function(fileObjOrUrl) {
        var url = fileObjOrUrl.url || fileObjOrUrl;
        if(!url) return '';
        
        var result = '',
            base_url = '';
        
        // New file urls include attachment host, so we don't need to prepend it
        var fUrl = kuma.url.parse(url);
        if (!fUrl.host) {
            var p = kuma.url.parse(env.url, true),
                base_url = p.protocol + '//' + p.host;
        }
        url = base_url + url;
        return cacheFn('kuma:get_attachment_content:' + md5(url.toLowerCase()), 3600, function(next) {
            try {
                request({
                    method: 'GET',
                    headers: { 'Cache-Control': env.cache_control },
                    url: url
                }, function(err, resp, body) {
                    if(resp && 200 == resp.statusCode) {
                        next(body);
                    }
                    else if(err) {
                        next(null);
                    }
                });
            } catch(e) {
                next("error: " + e);
            }
        });
    },

    /**
     * #### cacheFnIgnoreCacheControl
     * Cache a function, and use cached results no matter what 
     * Cache-Control we get from a shift-refresh.
     */
    cacheFnIgnoreCacheControl: function (key, tm_out, to_cache) {
        var result = null,
            err_result = null,
            f = new Future(),
            mc = memcached;
        mc.get(key, function (err, c_result) {
            if (c_result) {
                result = c_result;
                f['return']();
            } else {
                try {
                    to_cache(function (val) {
                        mc.set(key, val, tm_out, function (err, c_result) {
                            result = val;
                            f['return']();
                        });
                    });
                } catch (e) {
                    err_result = e;
                    result = '';
                    f['return']();
                }
            }
        });
        f.wait();
        if (err_result) { throw err_result; }
        return result;
    },
    
    // #### memcacheSet(key, value, timeout)
    //
    // Store a value in memcache with the given key and timeout (in seconds)
    memcacheSet: function (key, value, tmout) {
        var result = null,
            err_result = null,
            f = new Future(),
            mc = memcached;
        mc.set(key, value, tmout, function (err, c_result) {
            err_result = err;
            result = c_result;
            f['return']();
        });
        f.wait();
        if (err_result) { throw err_result; }
        return result;
    },
    
    // #### memcacheGet(key)
    //
    // Fetch the value for a key from memcache
    memcacheGet: function (key) {
        var result = null,
            err_result = null,
            f = new Future(),
            mc = memcached;
        mc.get(key, function (err, c_result) {
            err_result = err;
            result = c_result;
            f['return']();
        });
        f.wait();
        if (err_result) { throw err_result; }
        return result;
    },
    
    // #### defaults(object, *defaults)
    //
    // Fill in undefined properties in object with values from the defaults 
    // objects, and return the object. As soon as the property is filled, 
    // further defaults will have no effect.
    //
    // Stolen from http://underscorejs.org/#defaults
    defaults: function (obj) {
        Array.prototype.slice.call(arguments, 1).forEach(function(source) {
            if (source) {
                for (var prop in source) {
                    if (obj[prop] === void 0) obj[prop] = source[prop];
                }
            }
        });
        return obj;
    },
        
    // #### fetchJSONResource
    // Fetch an HTTP resource with JSON representation, parse the JSON and 
    // return a JS object.
    fetchJSONResource: function (url, opts) {
        opts = MDN.defaults(opts || {}, {
            headers: { 'Cache-Control': env.cache_control, 
                       'Accept': 'application/json',
                       'Content-Type': 'application/json' },
        });
        return JSON.parse(MDN.fetchHTTPResource(url, opts));
    },
    
    // #### fetchHTTPResource
    // Fetch an HTTP resource, return the response body.
    fetchHTTPResource: function (url, opts) {
        opts = MDN.defaults(opts || {}, {
            method: 'GET',
            headers: { 'Cache-Control': env.cache_control, 
                       'Accept': "text/plain",
                       'Content-Type': "text/plain" },
            url: url,
            cache_key: 'kuma:http_resource:' + md5(url.toLowerCase()),
            cache_timeout: 3600,
            ignore_cache_control: false
        });
        var to_cache = function (next) {
            try {
                var req = request.get(opts);
                req.on('response', function(res) {
                    var chunks = [];
                    var content_length = 0;
                    res.on('error', function(chunk) {
                        next(null);
                    });
                    res.on('data', function(chunk) {
                        chunks.push(chunk);
                        content_length += chunk.length;
                    });
                    res.on('end', function() {
                        var buffer = new Buffer(content_length);
                        var offset = 0;
                        for (var i=0; i<chunks.length; i++) {
                            chunks[i].copy(buffer, offset);
                            offset += chunks[i].length;
                        }
                        var encoding = res.headers['content-encoding'];
                        if (encoding == 'gzip') {
                            zlib.gunzip(buffer, function(err, decoded) {
                                next(decoded && decoded.toString());
                            });
                        } else if (encoding == 'deflate') {
                            zlib.inflate(buffer, function(err, decoded) {
                              next(decoded && decoded.toString());
                            })
                        } else {
                            next(buffer.toString());
                        }
                    });
                });                 
                req.on('error', function(err) { next(null); });                
            } catch (e) {
                next(null);
            }            
        };
        if (opts.ignore_cache_control) {
            return MDN.cacheFnIgnoreCacheControl(opts.cache_key, opts.cache_timeout, to_cache);
        } else {
            return cacheFn(opts.cache_key, opts.cache_timeout, to_cache);
        }
    },
    
    /* Returns the appropriate string (usually a comma+space) for usage in a enumeration list for the current locale */
    listSeparator: function() {
        var listSeparators = { "en-US": ", ", "ar": "،", "fa": "،", "ja": "、", "ko": "·", "mn": "᠂", "ur": "،", "zh−TW": "、" };
        return mdn.localString(listSeparators);
    },
    
    /*
     * FILE READING
     *
     * Utilities to read various files.
     */

    CSVToArray: function( strData, strDelimiter ) {
      // Check to see if the delimiter is defined. If not,
      // then default to comma.
      strDelimiter = (strDelimiter || ",");
    
      // Create a regular expression to parse the CSV values.
      var objPattern = new RegExp(
        (
          // Delimiters.
          "(\\" + strDelimiter + "|\\r?\\n|\\r|^)" +
    
          // Quoted fields.
          "(?:\"([^\"]*(?:\"\"[^\"]*)*)\"|" +
    
          // Standard fields.
          "([^\"\\" + strDelimiter + "\\r\\n]*))"
        ),
        "gi"
        );
    
    
      // Create an array to hold our data. Give the array
      // a default empty first row.
      var arrData = [[]];
    
      // Create an array to hold our individual pattern
      // matching groups.
      var arrMatches = null;
    
    
      // Keep looping over the regular expression matches
      // until we can no longer find a match.
      while (arrMatches = objPattern.exec( strData )){
    
        // Get the delimiter that was found.
        var strMatchedDelimiter = arrMatches[ 1 ];
    
        // Check to see if the given delimiter has a length
        // (is not the start of string) and if it matches
        // field delimiter. If id does not, then we know
        // that this delimiter is a row delimiter.
        if (
          strMatchedDelimiter.length &&
          (strMatchedDelimiter != strDelimiter)
          ){
    
          // Since we have reached a new row of data,
          // add an empty row to our data array.
          arrData.push( [] );
    
        }
    
    
        // Now that we have our delimiter out of the way,
        // let's check to see which kind of value we
        // captured (quoted or unquoted).
        if (arrMatches[ 2 ]){
    
          // We found a quoted value. When we capture
          // this value, unescape any double quotes.
          var strMatchedValue = arrMatches[ 2 ].replace(
            new RegExp( "\"\"", "g" ),
            "\""
            );
    
        } else {
    
          // We found a non-quoted value.
          var strMatchedValue = arrMatches[ 3 ];
    
        }
    
    
        // Now that we have our value string, let's add
        // it to the data array.
        arrData[ arrData.length - 1 ].push( strMatchedValue );
      }
    
      // Return the parsed data.
      return( arrData );
    },
    
    loadArrayFromCSV: function(url, separator) {
        url = url.replace(/&amp;/i, "&");
        var html = MDN.fetchHTTPResource(url, {
            headers: { 'Cache-Control': env.cache_control, 
                       'Accept': 'text/csv',
                       'Content-Type': 'text/csv' },
        });
        return MDN.CSVToArray(html, separator);
    }
} %>