angular-cn/public/_includes/_util-fns.jade

409 lines
15 KiB
Plaintext

//- Mixins and associated functions
//- _docsFor: used to identify the language this version of the docs if for;
//- Should be one of: 'ts', 'dart' or 'js'. Set in lang specific _util-fns file.
- var _docsFor = '';
//- Should match `_docsFor`, but in this case provides the full capitalized
//- name of the language.
- var _Lang = 'TypeScript';
//- Simple "macros" used via interpolation in text:
//- e.g., the #{_priv}el variable has an `@Input` #{_decorator}.
//- Use #{_decorator} whereever the word "decorator" is expected, provided it is not
//- preceded by the article "a". (E.g., will be "annotation" for Dart)
- var _decorator = 'decorator';
//- Articles (which toggle between 'a' and 'an'). Used for, e.g.,
//- array vs. list; decorator vs. annotation.
- var _a = 'a';
- var _an = 'an';
//- TS arrays vs. Dart lists
- var _array = 'array';
//- Deprecate now that we have the articles _a and _an
- var _an_array = 'an array';
//- Promise vs. Future, etc
- var _Promise = 'Promise';
- var _Observable = 'Observable';
//- Location of sample code
- var _liveLink = 'live link';
//- Used to prefix identifiers that are private. In Dart this will be '_'.
- var _priv = '';
//- Use to conditionally include the block that follows +ifDocsFor(...).
//- Generally favor use of Jade named blocks instead. ifDocsFor is convenient
//- for prose that should appear only in one language version.
mixin ifDocsFor(lang)
if _docsFor.toLowerCase() === lang.toLowerCase()
block
//- Use to map inlined (prose) TS paths into, say, Dart paths via the
//- adjustExamplePath transformer function.
mixin adjExPath(path)
if adjustExamplePath
| #{adjustExamplePath(path)}
else
| #{path}
mixin includeShared(filePath, region)
- var newPath = translatePath(filePath, region);
!=partial(newPath)
mixin makeExample(_filePath, region, _title, stylePatterns)
- var filePath = adjustExamplePath ? adjustExamplePath(_filePath) : _filePath;
- var title = adjustExampleTitle ? adjustExampleTitle(_title) : _title;
- var language = attributes.language || getExtn(filePath);
- var frag = getFrag(filePath, region);
- var defaultFormat = frag.split('\n').length > 2 ? "linenums" : "";
- var format = attributes.format || defaultFormat;
- if (attributes.format === '.') format = '';
- var avoid = !!attributes.avoid;
if (title)
if (avoid)
.example-title.avoid AVOID: #{title}
else
.example-title #{title}
code-example(language="#{language}" format="#{format}")
!= styleString(frag, stylePatterns)
//- Like makeExample, but the first argument is a path that is
//- relative to the project root. Unless title is defined,
//- the project relative path will be used.
mixin makeProjExample(projRootRelativePath, region, title, stylePatterns)
- var relPath = projRootRelativePath.trim();
- var filePath = getExampleName() + '/ts/' + relPath;
- if (!title) {
- // Is path like styles.1.css? Then drop the '.1' qualifier:
- var matches = relPath.match(/^(.*)\.\d(\.\w+)$/);
- title = matches ? matches[1] + matches[2] : relPath;
- }
+makeExample(filePath, region, title, stylePatterns)
//- Like makeExample, but doesn't show line numbers, and the first
//- argument is a path that is relative to the example project root.
//- Unless title is defined, the project relative path will be used.
//- Title will always end with a phrase in parentheses; if no such
//- ending is given, then the title will be suffixed with
//- either "(excerpt)", or "(#{region})" when region is defined.
mixin makeExcerpt(projRootRelativePath, region, title, stylePatterns)
- var relPath = projRootRelativePath.trim();
- var filePath = getExampleName() + '/ts/' + relPath;
- if (!title) {
- // Is path like styles.1.css? Then drop the '.1' qualifier:
- var matches = relPath.match(/^(.*)\.\d(\.\w+)$/);
- title = matches ? matches[1] + matches[2] : relPath;
- }
- var excerpt = region || 'excerpt';
- if (title && !title.match(/\([\w ]+\)$/)) title = title + ' (' + excerpt + ')';
+makeExample(filePath, region, title, stylePatterns)(format='.')
//- Extract the doc example name from `current`.
- var getExampleName = function() {
- var dir = current.path[current.path.length - 1];
- return dir == 'latest' ? current.source : dir;
- };
mixin makeTabs(filePaths, regions, tabNames, stylePatterns)
- filePaths = strSplit(filePaths);
- if (adjustExamplePath) filePaths = filePaths.map(adjustExamplePath);
- regions = strSplit(regions, filePaths.length);
- tabNames = strSplit(tabNames, filePaths.length);
- if (adjustExampleTitle) tabNames = tabNames.map(adjustExampleTitle);
code-tabs
each filePath,index in filePaths
- var region = regions[index].trim();
- var tabName = tabNames[index].trim();
- var language = attributes.language || getExtn(filePath);
- var format = attributes.format || "linenums";
- var frag = getFrag(filePath, region);
- var sps = Array.isArray(stylePatterns) ? stylePatterns[index] : stylePatterns;
code-pane(language="#{language}" name="#{tabName}" format="#{format}")
!= styleString(frag, sps)
mixin makeJson( filePath, jsonConfig, title, stylePatterns)
- var language = attributes.language || getExtn(filePath);
- var format = attributes.format || "linenums";
- var frag = getFrag(filePath, '');
- var json = unescapeHtml(frag);
- var jsonExtract = extractJson(json, jsonConfig);
- var avoid = !!attributes.avoid;
if (title)
if (avoid)
.example-title.avoid #{title}
else
.example-title #{title}
code-example(language="#{language}" format="#{format}")
if (jsonExtract == 'ERROR')
err ERROR: Unable to extract json using config: "#{jsonConfig.toString()}"
else
!= styleString(jsonExtract, stylePatterns)
- // Open (and close) an explanation <div>. See QuickStart
script.
function why(id, backTo) {
var id = "#"+id;
var el = document.querySelector(id);
el.hidden=el.hidden=!el.hidden;
if (el.hidden && backTo){
// the next line is required to work around a bug in WebKit (Chrome / Safari)
location.href = "#";
location.href = "#" + backTo;
}
}
script.
function verbose(isVerbose) {
isVerbose = !! isVerbose;
var el = document.querySelector('button.verbose.off');
el.style.display = isVerbose ? 'block' : 'none';
var el = document.querySelector('button.verbose.on');
el.style.display = isVerbose ? 'none' : 'block';
CCSStylesheetRuleStyle('main','.l-verbose-section', 'display',
isVerbose ? 'block' : 'none');
}
script.
function CCSStylesheetRuleStyle(stylesheet, selectorText, style, value){
/* returns the value of the element style of the rule in the stylesheet
* If no value is given, reads the value
* If value is given, the value is changed and returned
* If '' (empty string) is given, erases the value.
* The browser will apply the default one
*
* string stylesheet: part of the .css name to be recognized, e.g. 'default'
* string selectorText: css selector, e.g. '#myId', '.myClass', 'thead td'
* string style: camelCase element style, e.g. 'fontSize'
* string value optional : the new value
*/
var CCSstyle = undefined, rules, sheet;
for(var m in document.styleSheets){
sheet = document.styleSheets[m];
if(sheet.href && sheet.href.indexOf(stylesheet) != -1){
rules = sheet[document.all ? 'rules' : 'cssRules'];
for(var n in rules){
console.log(rules[n].selectorText);
if(rules[n].selectorText == selectorText){
CCSstyle = rules[n].style;
break;
}
}
break;
}
}
if(value == undefined)
return CCSstyle[style]
else
return CCSstyle[style] = value
}
//---------------------------------------------------------------------------------------------------------
- var translatePath = function(filePath, region) {
- filePath = filePath.trim();
- var regionPad = (region && region.length) ? '-' + region.toString() : '';
- var matches = /{(.*)}.*/.exec(filePath);
- if (matches) {
- var topLevelDir = matches[1];
- var currentPath = current.path;
- var subPaths = currentPath.slice(2);
- // subPaths[subPaths.length - 1] = "_." + subPaths[subPaths.length - 1];
- subPaths[subPaths.length - 1] = "_fragments/" + subPaths[subPaths.length - 1];
- var newPath = getPathToDocs() + topLevelDir + '/' + subPaths.join("/");
- var result = newPath + regionPad + ".jade";
- } else {
- var extn = getExtn(filePath);
- var baseFileName = getBaseFileName(filePath);
- var noExtnFileName = baseFileName.substr(0,baseFileName.length - (extn.length + 1));
- var folder = getFolder(filePath);
- // var result = folder + "/_." + noExtnFileName + regionPad + "." + extn;
- var result = folder + "/_fragments/" + noExtnFileName + regionPad + "." + extn;
- }
- return result
- }
- var EMPTY_STRINGS = [ '','','','','','',''];
- var strSplit = function(str, length) {
- var res;
- str = str || '';
- if (!length) {
- res = str.split(",");
- } else {
- res = str.split(",");
- if (res.length < length) {
- res = res.concat(EMPTY_STRINGS.slice(0, length - res.length));
- }
- }
- return res;
- }
- var getFrag = function(filePath, region) {
- var fullFileName = getFragFilePath(filePath, region);
- var frag = partial(fullFileName);
- if (frag == null) {
- return "BAD FILENAME: " + fullFileName + " Current path: " + current.path + " PathToDocs: " + getPathToDocs();
- } else {
- // ``` gets translated to <pre><code>.....</code></pre> and we need
- // to remove this from the fragment prefix is 11 long and suffix is 13 long
- frag = frag.substring(11, frag.length-13);
- // Uncomment next line for debugging.
- // frag = "FileName: " + fullFileName + " Current path: " + current.path + " PathToDocs: " + getPathToDocs() + "\n" + frag;
- return frag;
- }
- }
- var extractJson = function(json, jsonConfig ) {
- try {
- if (jsonConfig) {
- return extractJsonFragment(json, jsonConfig.rootPath || null, jsonConfig.paths || [], jsonConfig.space || " ");
- } else {
- return json;
- }
- } catch (e) {
- return "ERROR";
- // return json;
- }
- }
- var unescapeHtml = function(s) {
- // can't break across multiple lines because of jade limitations.
- return s.replace(/&amp;/g, '&').replace(/&lt;/g, '<').replace(/&gt;/g, '>').replace(/&quot;/g, '"').replace(/&#039/g, "'");
- }
- var styleString = function(source, stylePatterns) {
- if (stylePatterns) {
- for (var styleName in stylePatterns) {
- var rxs = stylePatterns[styleName];
- rxs = Array.isArray(rxs) ? rxs : [rxs];
- rxs.forEach(function(rx) {
- source = applyStyle(source, styleName, rx );
- });
- }
- }
- return source;
- }
- var getFragFilePath = function (filePath, region) {
- filePath = filePath.trim();
- var extn = getExtn(filePath);
- var fileBase = filePath.substr(0,filePath.length - (extn.length + 1));
- var regionPad = (region && region.length) ? '-' + region.toString() : '';
- var fullFileName = getPathToFrags() + fileBase + regionPad + "." + extn + '.md';
- return fullFileName;
- }
//- styles a string according to a regular expression.
//- The match groups resulting from the regexp application are what is styled
//- (not the whole regexp).
- var applyStyle = function(str, styleName, rx) {
- var repls = {};
- var matches;
- do {
- matches = rx.exec(str);
- if (matches) {
- matches.slice(1).forEach(function(match) {
- var repl = '<span class="' + styleName + '">' + match + '</span>';
- repls[match] = { repl: repl, isGlobal: rx.global };
- });
- }
- } while (matches != null && rx.global );
- for (var match in repls) {
- var repl = repls[match];
- // var escapedMatch = match.replace(/\\/g,'\\').replace(/\(/g,'\(').replace(/\)/g, '\)').replace(/\./,'\.');
- // var rx2 = new RegExp(escapedMatch, repl.isGlobal ? "g" : "");
- var rx2 = match;
- str = str.replace(rx2, repl.repl);
- };
- return str;
- }
- var getExtn = function(fileName) {
- var ix = fileName.lastIndexOf('.');
- return ix > 0 ? fileName.substr(ix+1) : "";
- }
- var getBaseFileName = function(fileName) {
- var ix = fileName.lastIndexOf('/');
- return ix > 0 ? fileName.substr(ix+1) : "";
- }
- var getFolder = function(fileName) {
- var ix = fileName.lastIndexOf('/');
- return ix > 0 ? fileName.substr(0, ix) : "";
- }
- var getPathToDocs = function() {
- // simple way to only take as many '../' sections as we need to back up to the 'docs' dir
- // from the current document
- // we will almost certainly never go 10 or 11 deep but ...
- return current.pathToDocs || "../../../../../../../../../../../".substr(0, (current.path.length-2)*3);
- }
- var getPathToFrags = function() {
- return getPathToDocs() + "_fragments/";
- }
- var getPathToExamples = function() {
- return getPathToDocs() + "_examples/";
- }
//- Extract a subset of a json file in a specified order defined
//- by extractPaths while retaining original order for any
//- unspecified subobjects.
//-
//- based on the principle that JSON.parse(source) constructs objects
//- in order from the top down in 'source' and JSON.stringify(source) iterates 'source'
//- properties according to the order in which they were inserted. ( the spec actually
//- discourages this assumption but this method will only
//- run on node (v8) and the assumption seems safe there. )
- function extractJsonFragment(source, rootPath, extractPaths, space) {
- var objSource = JSON.parse(source);
- if (rootPath && rootPath.length > 0) {
- objSource = getSubObject(objSource, rootPath);
- }
- var objDest = {};
- extractPaths.trim().split(",").forEach(function(dotPath) {
- processPath(objSource, objDest, dotPath );
- });
- var result = JSON.stringify(objDest, null, space || " ");
- return result;
- function getSubObject(source, path) {
- var nextSource = source;
- var pathParts = path.trim().split(".");
- while (pathParts.length > 0) {
- var nextProp = pathParts.shift();
- nextSource = nextSource[nextProp];
- }
- return nextSource;
- }
- function processPath(source, dest, dotPath) {
- var nextSource = source;
- var nextDest = dest;
- var pathParts = dotPath.trim().split(".");
- while (pathParts.length > 0) {
- var nextProp = pathParts.shift();
- nextSource = nextSource[nextProp];
- if (pathParts.length > 0) {
- var val = nextDest[nextProp] || {};
- nextDest[nextProp] = val;
- nextDest = val;
- } else {
- nextDest[nextProp] = nextSource;
- }
- }
- }
- }