Beispiel #1
0
  /**
   * build common layout output.
   * @return {IceCap} layout output.
   * @private
   */
  _buildLayoutDoc() {
    let info = this._getInfo();

    let ice = new IceCap(this._readTemplate('layout.html'), {autoClose: false});

    ice.text('esdocVersion', `(${this._config._esdocVersion})`);
    if (info.url) {
      ice.attr('repoURL', 'href', info.url);
      if (info.url.match(new RegExp('^https?://github.com/'))) {
        ice.attr('repoURL', 'class', 'repo-url-github');
      }
    } else {
      ice.drop('repoURL');
    }

    ice.drop('testLink', !this._config.test);

    // see StaticFileBuilder#exec
    ice.loop('userScript', this._config.scripts || [], (i, userScript, ice)=>{
      let name = `user/script/${i}-${path.basename(userScript)}`;
      ice.attr('userScript', 'src', name);
    });

    ice.loop('userStyle', this._config.styles || [], (i, userStyle, ice)=>{
      let name = `user/css/${i}-${path.basename(userStyle)}`;
      ice.attr('userStyle', 'href', name);
    });

    ice.load('nav', this._buildNavDoc());
    return ice;
  }
Beispiel #2
0
  /**
   * build summary output html by docs.
   * @param {DocObject[]} docs - target docs.
   * @param {string} title - summary title.
   * @param {boolean} innerLink - if true, link in summary is inner link.
   * @return {IceCap} summary output.
   * @private
   */
  _buildSummaryDoc(docs, title, innerLink) {
    if (docs.length === 0) return;

    let ice = new IceCap(this._readTemplate('summary.html'));

    ice.text('title', title);
    ice.loop('target', docs, (i, doc, ice)=>{
      ice.text('generator', doc.generator ? '*' : '');
      ice.load('name', this._buildDocLinkHTML(doc.longname, null, innerLink, doc.kind));
      ice.load('signature', this._buildSignatureHTML(doc));
      ice.load('description', shorten(doc, true));
      ice.text('abstract', doc.abstract ? 'abstract' : '');
      ice.text('access', doc.access);
      if (['get', 'set'].includes(doc.kind)) {
        ice.text('kind', doc.kind);
      } else {
        ice.drop('kind');
      }

      if (['member', 'method', 'get', 'set'].includes(doc.kind)) {
        ice.text('static', doc.static ? 'static' : '');
      } else {
        ice.drop('static');
      }

      ice.text('since', doc.since);
      ice.load('deprecated', this._buildDeprecatedHTML(doc));
      ice.load('experimental', this._buildExperimentalHTML(doc));
      ice.text('version', doc.version);
    });

    return ice;
  }
Beispiel #3
0
  /**
   * build test describe list html.
   * @param {number} [depth=0] - test depth.
   * @param {string} [memberof] - target test.
   * @returns {string} html of describe list.
   * @private
   */
  _buildTestDescribeDocHTML(depth = 0, memberof = null) {
    let cond = {kind: 'testDescribe', testDepth: depth};
    if (memberof) cond.memberof = memberof;
    let describeDocs = this._orderedFind('testId asec', cond);
    let padding;
    let html = '';

    for (let describeDoc of describeDocs) {
      let ice = new IceCap(this._readTemplate('testDescribe.html'));

      let testCount = this._find({kind: 'testIt', longname: {regex: new RegExp(`^${describeDoc.longname}\\.`)}}).length;
      padding = 10 * (depth + 1);
      ice.attr('testDescribe', 'data-test-depth', depth);
      ice.into('testDescribe', describeDoc, (describeDoc, ice)=>{
        let descriptionHTML = this._buildFileDocLinkHTML(describeDoc, describeDoc.description);

        let testTargetsHTML = [];
        for (let testTarget of describeDoc._custom_test_targets || []) {
          testTargetsHTML.push(this._buildDocLinkHTML(testTarget[0], testTarget[1]));
        }
        testTargetsHTML = testTargetsHTML.join('\n') || '-';

        ice.load('testDescription', descriptionHTML);
        ice.attr('testDescription', 'style', `padding-left: ${padding}px`);
        ice.load('testTarget', testTargetsHTML);
        ice.text('testCount', testCount);
      });

      padding = 10 * (depth + 2);
      let itDocs = this._orderedFind('testId asec', {kind: 'testIt', testDepth: depth + 1, memberof: describeDoc.longname});
      ice.loop('testIt', itDocs, (i, itDoc, ice)=>{
        let descriptionHTML = this._buildFileDocLinkHTML(itDoc, itDoc.description);

        let testTargetsHTML = [];
        for (let testTarget of itDoc._custom_test_targets || []) {
          testTargetsHTML.push(this._buildDocLinkHTML(testTarget[0], testTarget[1]));
        }
        testTargetsHTML = testTargetsHTML.join('\n') || '-';

        ice.attr('testIt', 'data-test-depth', depth + 1);
        ice.load('testDescription', descriptionHTML);
        ice.attr('testDescription', 'style', `padding-left: ${padding}px`);
        ice.load('testTarget', testTargetsHTML);
      });

      let innerDescribeHTML = this._buildTestDescribeDocHTML(depth + 1, describeDoc.longname);

      html += '\n' + ice.html + '\n' + innerDescribeHTML;
    }

    return html;
  }
Beispiel #4
0
  /**
   * built manual index.
   * @param {ManualConfigItem[]} manualConfig - target manual config.
   * @return {IceCap} built index.
   * @private
   */
  _buildManualIndex(manualConfig) {
    const ice = new IceCap(this._readTemplate('manualIndex.html'));

    ice.loop('manual', manualConfig, (i, item, ice)=>{
      const toc = [];
      if (item.references) {
        const identifiers = this._findAllIdentifiersKindGrouping();
        if (identifiers.class.length) toc.push({label: 'Class', link: 'identifiers.html#class', indent: 'indent-h1'});
        if (identifiers.interface.length) toc.push({label: 'Interface', link: 'identifiers.html#interface', indent: 'indent-h1'});
        if (identifiers.function.length) toc.push({label: 'Function', link: 'identifiers.html#function', indent: 'indent-h1'});
        if (identifiers.variable.length) toc.push({label: 'Variable', link: 'identifiers.html#variable', indent: 'indent-h1'});
        if (identifiers.typedef.length) toc.push({label: 'Typedef', link: 'identifiers.html#typedef', indent: 'indent-h1'});
        if (identifiers.external.length) toc.push({label: 'External', link: 'identifiers.html#external', indent: 'indent-h1'});
      } else {
        const fileName = this._getManualOutputFileName(item);
        const html = this._convertMDToHTML(item);
        const $root = cheerio.load(html).root();
        const isHRise = $root.find('h1').length === 0;
        $root.find('h1,h2,h3,h4,h5').each((i, el)=>{
          const $el = cheerio(el);
          const label = $el.text();
          const link = `${fileName}#${$el.attr('id')}`;
          let indent;
          if (isHRise) {
            const tagName = `h${parseInt(el.tagName.charAt(1), 10) - 1}`;
            indent = `indent-${tagName}`;
          } else {
            indent = `indent-${el.tagName.toLowerCase()}`;
          }
          toc.push({label, link, indent});
        });
      }

      ice.attr('manual', 'data-toc-name', item.label.toLowerCase());
      ice.text('title', item.label);
      ice.attr('title', 'href', this._getManualOutputFileName(item));
      ice.loop('manualNav', toc, (i, item, ice)=>{
        ice.attr('manualNav', 'class', item.indent);
        ice.text('link', item.label);
        ice.attr('link', 'href', item.link);
      });
    });

    return ice;
  }
Beispiel #5
0
  /**
   * build properties output.
   * @param {ParsedParam[]} [properties=[]] - properties in doc object.
   * @param {string} title - output title.
   * @return {IceCap} built properties output.
   * @private
   */
  _buildProperties(properties = [], title = 'Properties:') {
    let ice = new IceCap(this._readTemplate('properties.html'));

    ice.text('title', title);

    ice.loop('property', properties, (i, prop, ice)=>{
      ice.autoDrop = false;
      ice.attr('property', 'data-depth', prop.name.split('.').length - 1);
      ice.text('name', prop.name);
      ice.attr('name', 'data-depth', prop.name.split('.').length - 1);
      ice.load('description', prop.description);

      let typeNames = [];
      for (var typeName of prop.types) {
        typeNames.push(this._buildTypeDocLinkHTML(typeName));
      }
      ice.load('type', typeNames.join(' | '));

      // appendix
      let appendix = [];
      if (prop.optional) {
        appendix.push('<li>optional</li>');
      }
      if ('defaultValue' in prop) {
        appendix.push(`<li>default: ${prop.defaultValue}</li>`);
      }
      if (typeof prop.nullable === 'boolean') {
        appendix.push(`<li>nullable: ${prop.nullable}</li>`);
      }
      if (appendix.length) {
        ice.load('appendix', `<ul>${appendix.join('\n')}</ul>`);
      } else {
        ice.text('appendix', '');
      }
    });

    if (!properties || properties.length === 0) {
      ice.drop('properties');
    }

    return ice;
  }
Beispiel #6
0
  /**
   * build common navigation output.
   * @return {IceCap} navigation output.
   * @private
   */
  _buildNavDoc() {
    let html = this._readTemplate('nav.html');
    let ice = new IceCap(html);

    const kinds = ['class', 'function', 'variable', 'typedef', 'external'];
    const allDocs = this._find({kind: kinds}).filter(v => !v.builtinExternal);
    const kindOrder = {class: 0, interface: 1, function: 2, variable: 3, typedef: 4, external: 5};
    allDocs.sort((a, b)=>{
      const filePathA = a.longname.split('~')[0].replace('src/', '');
      const filePathB = b.longname.split('~')[0].replace('src/', '');
      const dirPathA = path.dirname(filePathA);
      const dirPathB = path.dirname(filePathB);
      const kindA = a.interface ? 'interface' : a.kind;
      const kindB = b.interface ? 'interface' : b.kind;
      if (dirPathA === dirPathB) {
        if (kindA === kindB) {
          return a.longname > b.longname ? 1 : -1;
        } else {
          return kindOrder[kindA] > kindOrder[kindB] ? 1 : -1;
        }
      } else {
        return dirPathA > dirPathB ? 1 : -1;
      }
    });
    let lastDirPath = '.';
    ice.loop('doc', allDocs, (i, doc, ice)=>{
      const filePath = doc.longname.split('~')[0].replace(/^.*?[/]/, '');
      const dirPath = path.dirname(filePath);
      const kind = doc.interface ? 'interface' : doc.kind;
      const kindText = kind.charAt(0).toUpperCase();
      const kindClass = `kind-${kind}`;
      ice.load('name', this._buildDocLinkHTML(doc.longname));
      ice.load('kind', kindText);
      ice.attr('kind', 'class', kindClass);
      ice.text('dirPath', dirPath);
      ice.drop('dirPath', lastDirPath === dirPath);
      lastDirPath = dirPath;
    });

    return ice;
  }
Beispiel #7
0
  /**
   * build common navigation output.
   * @return {IceCap} navigation output.
   * @private
   */
  _buildNavDoc() {
    let html = this._readTemplate('nav.html');
    let ice = new IceCap(html);

    // class
    let classDocs = this._find({kind: 'class', interface: false});
    ice.drop('classWrap', !classDocs.length);
    ice.loop('classDoc', classDocs, (i, classDoc, ice)=>{
      ice.load('classDoc', this._buildDocLinkHTML(classDoc.longname));
    });

    // interface
    let interfaceDocs = this._find({kind: 'class', interface: true});
    ice.drop('interfaceWrap', !interfaceDocs.length);
    ice.loop('interfaceDoc', interfaceDocs, (i, interfaceDoc, ice)=>{
      ice.load('interfaceDoc', this._buildDocLinkHTML(interfaceDoc.longname));
    });

    // function
    let functionDocs = this._find({kind: 'function'});
    ice.drop('functionWrap', !functionDocs.length);
    ice.loop('functionDoc', functionDocs, (i, functionDoc, ice)=>{
      ice.load('functionDoc', this._buildDocLinkHTML(functionDoc.longname));
    });

    // variable
    let variableDocs = this._find({kind: 'variable'});
    ice.drop('variableWrap', !variableDocs.length);
    ice.loop('variableDoc', variableDocs, (i, variableDoc, ice)=>{
      ice.load('variableDoc', this._buildDocLinkHTML(variableDoc.longname));
    });

    // typedef
    let typedefDocs = this._find({kind: 'typedef'});
    ice.drop('typedefWrap', !typedefDocs.length);
    ice.loop('typedefDoc', typedefDocs, (i, typedefDoc, ice)=>{
      ice.load('typedefDoc', this._buildDocLinkHTML(typedefDoc.longname));
    });

    // external
    let externalDocs = this._find({kind: 'external'}).filter(v => !v.builtinExternal);
    ice.drop('externalWrap', !externalDocs.length);
    ice.loop('externalDoc', externalDocs, (i, externalDoc, ice)=>{
      ice.load('externalDoc', this._buildDocLinkHTML(externalDoc.longname));
    });

    return ice;
  }
Beispiel #8
0
  /**
   * build detail output html by docs.
   * @param {DocObject[]} docs - target docs.
   * @param {string} title - detail title.
   * @return {IceCap} detail output.
   * @private
   */
  _buildDetailDocs(docs, title) {
    let ice = new IceCap(this._readTemplate('details.html'));

    ice.text('title', title);
    ice.drop('title', !docs.length);

    ice.loop('detail', docs, (i, doc, ice)=>{
      let scope = doc.static ? 'static' : 'instance';
      ice.attr('anchor', 'id', `${scope}-${doc.kind}-${doc.name}`);
      ice.text('generator', doc.generator ? '*' : '');
      ice.text('name', doc.name);
      ice.load('signature', this._buildSignatureHTML(doc));
      ice.load('description', doc.description);
      ice.text('abstract', doc.abstract ? 'abstract' : '');
      ice.text('access', doc.access);
      if (['get', 'set'].includes(doc.kind)) {
        ice.text('kind', doc.kind);
      } else {
        ice.drop('kind');
      }
      if (doc.export && doc.importPath && doc.importStyle) {
        let link = this._buildFileDocLinkHTML(doc, doc.importPath);
        ice.into('importPath', `import ${doc.importStyle} from '${link}'`, (code, ice)=>{
          ice.load('importPathCode', code);
        });
      } else {
        ice.drop('importPath');
      }

      if (['member', 'method', 'get', 'set'].includes(doc.kind)) {
        ice.text('static', doc.static ? 'static' : '');
      } else {
        ice.drop('static');
      }

      ice.load('source', this._buildFileDocLinkHTML(doc, 'source'));
      ice.text('since', doc.since, 'append');
      ice.load('deprecated', this._buildDeprecatedHTML(doc));
      ice.load('experimental', this._buildExperimentalHTML(doc));
      ice.text('version', doc.version, 'append');
      ice.load('see', this._buildDocsLinkHTML(doc.see), 'append');
      ice.load('todo', this._buildDocsLinkHTML(doc.todo), 'append');
      ice.load('override', this._buildOverrideMethod(doc));

      let isFunction = false;
      if (['method', 'constructor', 'function'].indexOf(doc.kind) !== -1) isFunction = true;
      if (doc.kind === 'typedef' && doc.params && doc.type.types[0] === 'function') isFunction = true;

      if (isFunction) {
        ice.load('properties', this._buildProperties(doc.params, 'Params:'));
      } else {
        ice.load('properties', this._buildProperties(doc.properties, 'Properties:'));
      }

      // return
      if (doc.return) {
        ice.load('returnDescription', doc.return.description);
        let typeNames = [];
        for (let typeName of doc.return.types) {
          typeNames.push(this._buildTypeDocLinkHTML(typeName));
        }
        if (typeof doc.return.nullable === 'boolean') {
          let nullable = doc.return.nullable;
          ice.load('returnType', typeNames.join(' | ') + ` (nullable: ${nullable})`);
        } else {
          ice.load('returnType', typeNames.join(' | '));
        }

        ice.load('returnProperties', this._buildProperties(doc.properties, 'Return Properties:'));
      } else {
        ice.drop('returnParams');
      }

      // throws
      if (doc.throws) {
        ice.loop('throw', doc.throws, (i, exceptionDoc, ice)=>{
          ice.load('throwName', this._buildDocLinkHTML(exceptionDoc.types[0]));
          ice.load('throwDesc', exceptionDoc.description);
        });
      } else {
        ice.drop('throwWrap');
      }

      // fires
      if (doc.emits) {
        ice.loop('emit', doc.emits, (i, emitDoc, ice)=>{
          ice.load('emitName', this._buildDocLinkHTML(emitDoc.types[0]));
          ice.load('emitDesc', emitDoc.description);
        });
      } else {
        ice.drop('emitWrap');
      }

      // listens
      if (doc.listens) {
        ice.loop('listen', doc.listens, (i, listenDoc, ice)=>{
          ice.load('listenName', this._buildDocLinkHTML(listenDoc.types[0]));
          ice.load('listenDesc', listenDoc.description);
        });
      } else {
        ice.drop('listenWrap');
      }

      // example
      ice.into('example', doc.examples, (examples, ice)=>{
        ice.loop('exampleDoc', examples, (i, exampleDoc, ice)=>{
          let parsed = parseExample(exampleDoc);
          ice.text('exampleCode', parsed.body);
          ice.text('exampleCaption', parsed.caption);
        });
      });

      // tests
      ice.into('tests', doc._custom_tests, (tests, ice)=>{
        ice.loop('test', tests, (i, test, ice)=>{
          let testDoc = this._find({longname: test})[0];
          ice.load('test', this._buildFileDocLinkHTML(testDoc, testDoc.testFullDescription));
        });
      });
    });

    return ice;
  }