MDN may have intermittent access issues April 18 13:00 - April 19 01:00 UTC. See whistlepig.mozilla.org for all notifications.

mozilla

Revision 467291 of Template:DekiScript:Wiki

  • Revision slug: Template:DekiScript:Wiki
  • Revision title: Template:DekiScript:Wiki
  • Revision id: 467291
  • Created:
  • Creator: Sheppy
  • Is current revision? No
  • Comment
Tags: 

Revision Content

<% var wiki = module.exports = buildAPI({ /* * Given a MediaWiki path attempt to update it to a Kuma path * This is not a DekiScript function */ kumaPath: function(in_path) { // Strip the base path, allows this to replace Template:getRelativeURL path_strip = in_path.replace(RegExp('^https:\/\/developer\.mozilla\.org','i'),''); // Get/fix/update/add language var pathLang = (path_strip.match(/^\/?(\w{2}(?:[-|_]\w{2})?)?(?=\/)/)[1] || env.locale).replace(/^en$/i,'en-US').replace(/^(?:zh_)?cn$/i,'zh-CN').replace(/zh_tw/i,'zh-TW').replace(/^pt$/i,'pt-PT'); // Add fixed language and make sure there is docs and convert spaces to underscore var path = '/' + pathLang + path_strip.replace(/^(\/?\w{2}(?:[-|_]\w{2})?)?\/(?:docs\/)?/i,'/docs/').replace(/ /g,'_').replace(/%20/g,'_'); return path; }, // Given a path, attempt to construct an absolute URL to the wiki. // This is not a DekiScript function, but it's used by many of those below. buildAbsoluteURL: function (path) { var p = kuma.url.parse(env.url, true); var base_url = p.protocol + '//' + p.host; if (path.indexOf('/docs') == -1) { // HACK: If this looks like a legacy wiki URL, throw /en-US/docs // in front of it. That will trigger the proper redirection logic // until/unless URLs are corrected in templates base_url += '/en-US/docs'; } var re1 = / /gi; var re2 = /%20/gi; path = path.replace(re1, "_"); path = path.replace(re2, "_"); if (path.charAt(0) != '/') { base_url += '/'; } return base_url + path; }, // Check if the given wiki page exists. // [See also](http://developer.mindtouch.com/en/docs/DekiScript/Reference/Wiki_Functions_and_Variables/Wiki.PageExists) pageExists: function (path) { // Temporarily disabling this. // See: https://bugzilla.mozilla.org/show_bug.cgi?id=775590#c4 return true; var key = 'kuma:page_exists:' + md5(path.toLowerCase()); // This is an experiment to exempt wiki.pageExists // from shift-refresh cache busting: var mdn = require('MDN:Common'); //return cacheFn(key, 3600, function (next) { return mdn.cacheFnIgnoreCacheControl(key, 3600, function (next) { var opts = { method: 'HEAD', url: wiki.buildAbsoluteURL(path) }; try { request(opts, function (err, resp, body) { var result = false; if (resp && 200 == resp.statusCode) { result = true; } next(result); }); } catch (e) { next(false); } }); }, // Adjusts the visibility and heading levels of the specified HTML. // // The show parameter indicates whether or not the top level heading/title // should be displayed. The heading parameter sets the heading level of the // top level of the text to the specified value and adjusts all subsequent // headings accordingly. This adjustment happens regardless of the value of // show. // // heading is not supported at this time _adjustHeadings: function(html, show, heading) { if (show) { return html; } // Rip out the first header we find if (html) { html = html.replace(/^<(H|h)\d[^>]*>[^<]*(<\/B\d>|<\/h\d>)/ig,"") + ""; } return html; }, // Retrieve the content of a document for inclusion, optionally filtering // for a single section. // // Doesn't (yet?) support all the parameters offered by DekiScript, // but I don't think MDN pages use them all. Missing in particular: // revision, show, and heading // // [See also](http://developer.mindtouch.com/en/docs/DekiScript/Reference/Wiki_Functions_and_Variables/Wiki.Page) page: function (path, section, revision, show, heading) { var key = 'kuma:include:' + md5(path.toLowerCase()); return cacheFn(key, 3600, function (next) { var params = ['raw=1', 'macros=1', 'include=1']; if (section) { params.push('section='+encodeURIComponent(section)); } var opts = { method: 'GET', headers: { 'Cache-Control': env.cache_control }, url: wiki.buildAbsoluteURL(path) + '?' + params.join('&') }; try { request(opts, function (err, resp, body) { var result = ''; if (resp && 200 == resp.statusCode) { result = body || ''; if (show == undefined) { show = 0; } result = wiki._adjustHeadings(result, show, heading); } next(result); }); } catch (e) { next(''); } }); }, // Returns the page object for the specified page. // http://developer.mindtouch.com/en/docs/DekiScript/Reference/Wiki_Functions_and_Variables/Wiki.GetPage getPage: function (path) { var key = 'kuma:get_page:' + md5(path.toLowerCase()); return cacheFn(key, 3600, function (next) { var opts = { method: 'GET', headers: { 'Cache-Control': env.cache_control }, url: wiki.buildAbsoluteURL(path) + "$json" }; try { request(opts, function (err, resp, body) { var result = {}; if (resp && 200 == resp.statusCode) { result = JSON.parse(body); } next(result); }); } catch (e) { next({}); } }); }, // Returns a list of the headings for the specified page. // Each item in the returned list is an object with these fields: // // level: the heading level (1-6) // title: the heading's text title, as displayed to the user // // Parameters: // // path The path of the page whose headings should be returned // depth The maximum header level to return getHeadings: function(path, depth) { var html = wiki.page(path); if (!html || html.length == 0) { return NULL; } if (!depth) { depth = 3; } var re = /\(.+)\<\/h[1-6]\>/gi; var result; var list = []; while ((result = re.exec(html))) { var theLevel = result[1]; var theTitle = result[2]; if (theLevel <= depth) { var obj = {level: theLevel, title: theTitle }; list.push(obj); } } return list; }, // Retrieve the full uri of a given wiki page. // [See also](http://developer.mindtouch.com/en/docs/DekiScript/Reference/Wiki_Functions_and_Variables/Wiki.Uri) uri: function (path, query) { var out = wiki.buildAbsoluteURL(path); if (query) { out += '?' + query; } return out; }, // A link to the wiki page that you will add, that will be in a different language. // [See also](http://developer.mindtouch.com/en/docs/DekiScript/Reference/Wiki_Functions_and_Variables/Wiki.Languages) languages: function (langs) { // TODO var out = []; _.each(langs, function (url, lang) { out.push('
  • ', kuma.htmlEscape(lang), '
  • '); }); return "
      " + out.join('') + "<\/ul>"; }, // Inserts a pages sub tree // [See also](http://developer.mindtouch.com/en/docs/DekiScript/Reference/Wiki_Functions_and_Variables/Wiki.Tree) // if reverse is non-zero, the sort is backward // if ordered is true, the output is an
        instead of
          tree: function(path, depth, self, reverse, ordered) { var page = require('DekiScript:Page'); var pages = page.subpages(path, depth, self); if (reverse == 0) { pages.sort(alphanumForward); } else { pages.sort(alphanumBackward); } return process_array(pages, ordered != 0); function chunkify(t) { var tz = [], x = 0, y = -1, n = 0, i, j; while (i = (j = t.charAt(x++)).charCodeAt(0)) { var m = (i == 46 || (i >=48 && i <= 57)); if (m !== n) { tz[++y] = ""; n = m; } tz[y] += j; } return tz; } function alphanumForward(a, b) { var aa = chunkify(a.title); var bb = chunkify(b.title); for (x = 0; aa[x] && bb[x]; x++) { if (aa[x] !== bb[x]) { var c = Number(aa[x]), d = Number(bb[x]); if (c == aa[x] && d == bb[x]) { return c - d; } else return (aa[x] > bb[x]) ? 1 : -1; } } return aa.length - bb.length; } function alphanumBackward(a, b) { var bb = chunkify(a.title); var aa = chunkify(b.title); for (x = 0; aa[x] && bb[x]; x++) { if (aa[x] !== bb[x]) { var c = Number(aa[x]), d = Number(bb[x]); if (c == aa[x] && d == bb[x]) { return c - d; } else return (aa[x] > bb[x]) ? 1 : -1; } } return aa.length - bb.length; } function process_array(arr, ordered) { var result = ''; var openTag = '
            '; var closeTag = '
          '; if (ordered) { openTag = '
            '; closeTag = '
          '; } if(arr.length) { result += openTag; arr.forEach(function(item) { if (!item) { return; } result += '
        • ' + kuma.htmlEscape(item.title) + '' + process_array(item.subpages || [], ordered) + '
        • '; }); result += closeTag; } return result; } } }); %>

    Revision Source

    <% var wiki = module.exports = buildAPI({
        /*
        * Given a MediaWiki path attempt to update it to a Kuma path 
        * This is not a DekiScript function
        */
        kumaPath: function(in_path) {
            // Strip the base path, allows this to replace Template:getRelativeURL
            path_strip = in_path.replace(RegExp('^https:\/\/developer\.mozilla\.org','i'),'');
            // Get/fix/update/add language
            var pathLang = (path_strip.match(/^\/?(\w{2}(?:[-|_]\w{2})?)?(?=\/)/)[1] || env.locale).replace(/^en$/i,'en-US').replace(/^(?:zh_)?cn$/i,'zh-CN').replace(/zh_tw/i,'zh-TW').replace(/^pt$/i,'pt-PT');
            // Add fixed language and make sure there is docs and convert spaces to underscore
            var path = '/' + pathLang + path_strip.replace(/^(\/?\w{2}(?:[-|_]\w{2})?)?\/(?:docs\/)?/i,'/docs/').replace(/ /g,'_').replace(/%20/g,'_');
            return path;
        },
    
        // Given a path, attempt to construct an absolute URL to the wiki.
        // This is not a DekiScript function, but it's used by many of those below.
        buildAbsoluteURL: function (path) {
            var p = kuma.url.parse(env.url, true);
            var base_url = p.protocol + '//' + p.host;
    
            if (path.indexOf('/docs') == -1) {
                // HACK: If this looks like a legacy wiki URL, throw /en-US/docs 
                // in front of it. That will trigger the proper redirection logic 
                // until/unless URLs are corrected in templates
                base_url += '/en-US/docs';
            }
            var re1 = / /gi;
            var re2 = /%20/gi;
    
            path = path.replace(re1, "_");
            path = path.replace(re2, "_");
    
            if (path.charAt(0) != '/') { base_url += '/'; }
    
            return base_url + path;
        },
        
        // Check if the given wiki page exists.
        // [See also](http://developer.mindtouch.com/en/docs/DekiScript/Reference/Wiki_Functions_and_Variables/Wiki.PageExists)
        pageExists: function (path) {
            // Temporarily disabling this.
            // See: https://bugzilla.mozilla.org/show_bug.cgi?id=775590#c4
            return true;
            
            var key = 'kuma:page_exists:' + md5(path.toLowerCase());
            
            // This is an experiment to exempt wiki.pageExists 
            // from shift-refresh cache busting:
            var mdn = require('MDN:Common');
    
            //return cacheFn(key, 3600, function (next) {
            return mdn.cacheFnIgnoreCacheControl(key, 3600, function (next) {            
                var opts = { method: 'HEAD', url: wiki.buildAbsoluteURL(path) };
    
                try {
                    request(opts, function (err, resp, body) {
                        var result = false;
                        if (resp && 200 == resp.statusCode) {
                            result = true;
                        }
                        next(result);
                    });
                } catch (e) {
                    next(false);
                }
            });
        },
        
        // Adjusts the visibility and heading levels of the specified HTML.
        //
        // The show parameter indicates whether or not the top level heading/title
        // should be displayed. The heading parameter sets the heading level of the
        // top level of the text to the specified value and adjusts all subsequent
        // headings accordingly. This adjustment happens regardless of the value of
        // show.
        //
        // heading is not supported at this time
        _adjustHeadings: function(html, show, heading) {
            if (show) { return html; }
            
            // Rip out the first header we find
            if (html) { html = html.replace(/^<(H|h)\d[^>]*>[^<]*(<\/B\d>|<\/h\d>)/ig,"") + ""; }
            
            return html;
        },
            
        // Retrieve the content of a document for inclusion, optionally filtering 
        // for a single section.
        //
        // Doesn't (yet?) support all the parameters offered by DekiScript, 
        // but I don't think MDN pages use them all. Missing in particular: 
        // revision, show, and heading
        //
        // [See also](http://developer.mindtouch.com/en/docs/DekiScript/Reference/Wiki_Functions_and_Variables/Wiki.Page)
        page: function (path, section, revision, show, heading) {
            var key = 'kuma:include:' + md5(path.toLowerCase());
    
            return cacheFn(key, 3600, function (next) {
                var params = ['raw=1', 'macros=1', 'include=1'];
    
                if (section) { params.push('section='+encodeURIComponent(section)); }
    
                var opts = {
                    method: 'GET',
                    headers: { 'Cache-Control': env.cache_control },
                    url: wiki.buildAbsoluteURL(path) + '?' + params.join('&')
                };
    
                try {
                    request(opts, function (err, resp, body) {
                        var result = '';
                        if (resp && 200 == resp.statusCode) {
                            result = body || '';
                            if (show == undefined) {
                                show = 0;
                            }
                            result = wiki._adjustHeadings(result, show, heading);
                        }
                        next(result);
                    });
                } catch (e) {
                    next('');
                }
            });
        },
    
        // Returns the page object for the specified page.
        // http://developer.mindtouch.com/en/docs/DekiScript/Reference/Wiki_Functions_and_Variables/Wiki.GetPage
        getPage: function (path) {
            var key = 'kuma:get_page:' + md5(path.toLowerCase());
            return cacheFn(key, 3600, function (next) {
                var opts = {
                    method: 'GET',
                    headers: { 'Cache-Control': env.cache_control },
                    url: wiki.buildAbsoluteURL(path) + "$json"
                };
                try {
                    request(opts, function (err, resp, body) {
                        var result = {};
                        if (resp && 200 == resp.statusCode) {
                            result = JSON.parse(body);
                        }
                        next(result);
                    });
                } catch (e) {
                    next({});
                }
            });
        },
         
        // Returns a list of the headings for the specified page.
        // Each item in the returned list is an object with these fields:
        //
        //  level:  the heading level (1-6)
        //  title:  the heading's text title, as displayed to the user
        //
        // Parameters:
        //
        //  path    The path of the page whose headings should be returned
        //  depth   The maximum header level to return
        
        getHeadings: function(path, depth) {
            var html = wiki.page(path);
                    
            if (!html || html.length == 0) {
                return NULL;
            }
            
            if (!depth) {
                depth = 3;
            }
    
            var re = /\<h([1-6]).*?\>(.+)\<\/h[1-6]\>/gi;
            var result;
            var list = [];
            
            while ((result = re.exec(html))) {
                var theLevel = result[1];
                var theTitle = result[2];
                
                if (theLevel <= depth) {
                    var obj = {level: theLevel, title: theTitle };
                    list.push(obj);
                }
            }
            return list;
        },
    
        // Retrieve the full uri of a given wiki page.
        // [See also](http://developer.mindtouch.com/en/docs/DekiScript/Reference/Wiki_Functions_and_Variables/Wiki.Uri)
        uri: function (path, query) {
            var out = wiki.buildAbsoluteURL(path);
    
            if (query) { out += '?' + query; }
    
            return out;
        },
     
        // A link to the wiki page that you will add, that will be in a different language.
        // [See also](http://developer.mindtouch.com/en/docs/DekiScript/Reference/Wiki_Functions_and_Variables/Wiki.Languages)
        languages: function (langs) {
            // TODO
            var out = [];
            _.each(langs, function (url, lang) {
                out.push('<li><a href="', kuma.htmlEscape(url), '">',
                         kuma.htmlEscape(lang), '</a></li>');
            });
            return "<ul>" + out.join('') + "<\/ul>";
        },
    
        // Inserts a pages sub tree
        // [See also](http://developer.mindtouch.com/en/docs/DekiScript/Reference/Wiki_Functions_and_Variables/Wiki.Tree)
        // if reverse is non-zero, the sort is backward
        // if ordered is true, the output is an <ol> instead of <ul>
        tree: function(path, depth, self, reverse, ordered) {
            var page = require('DekiScript:Page');
            var pages = page.subpages(path, depth, self);
            
            if (reverse == 0) {
                pages.sort(alphanumForward);
            } else {
                pages.sort(alphanumBackward);
            }
            
            return process_array(pages, ordered != 0);
    
        	function chunkify(t) {
    			var tz = [], x = 0, y = -1, n = 0, i, j;
    
    			while (i = (j = t.charAt(x++)).charCodeAt(0)) {
                    var m = (i == 46 || (i >=48 && i <= 57));
    				if (m !== n) {
    					tz[++y] = "";
    	    			n = m;
    				}
    				tz[y] += j;
    			}
    			return tz;
    		}
    
            function alphanumForward(a, b) {
    
    			var aa = chunkify(a.title);
    			var bb = chunkify(b.title);
    
    			for (x = 0; aa[x] && bb[x]; x++) {
    				if (aa[x] !== bb[x]) {
    					var c = Number(aa[x]), d = Number(bb[x]);
    					if (c == aa[x] && d == bb[x]) {
    						return c - d;
    					} else return (aa[x] > bb[x]) ? 1 : -1;
    				}
    			}
    			return aa.length - bb.length;
    		}
    
            function alphanumBackward(a, b) {
    
        		var bb = chunkify(a.title);
    			var aa = chunkify(b.title);
    
    			for (x = 0; aa[x] && bb[x]; x++) {
    				if (aa[x] !== bb[x]) {
    					var c = Number(aa[x]), d = Number(bb[x]);
    					if (c == aa[x] && d == bb[x]) {
    						return c - d;
    					} else return (aa[x] > bb[x]) ? 1 : -1;
    				}
    			}
    			return aa.length - bb.length;
    		}
    
            function process_array(arr, ordered) {
                var result = '';
                var openTag = '<ul>';
                var closeTag = '</ul>';
                
                if (ordered) {
                    openTag = '<ol>';
                    closeTag = '</ol>';
                }
                
                if(arr.length) {
                    result += openTag;
                    arr.forEach(function(item) {
                        if (!item) { return; }
                        result += '<li><a href="' + item.url + '">' + kuma.htmlEscape(item.title) + '</a>' +
                                  process_array(item.subpages || [], ordered) + '</li>';
                        
                    });
                    result += closeTag;
                }
                return result;
            }   
        }
         
    }); %>
    Revert to this revision