Exemplo n.º 1
0
        mainHtmlPaths.map(mainHtmlPath => {
          var analyzer = new PolymerAnalyzer({
            urlLoader: new FSUrlLoader("/"),
            urlResolver: new PackageUrlResolver(),
          });

          var dirName = path.dirname(mainHtmlPath);
          var skipItem = item => path.relative(dirName, "/" + item.sourceRange.file).includes("..");

          return analyzer.analyze(mainHtmlPath).then(document => {
            var elements = document.getByKind('element');
            elements.forEach(element => {
              if (skipItem(element)) return;

              data.elementsByTagName[element.tagName] = element;
              remove(data.elementsByTagName[element.tagName])
            });
            var behaviors = document.getByKind('behavior');
            behaviors.forEach(behavior => {
              if (skipItem(behavior)) return;

              data.behaviorsByName[behavior.className] = behavior;
              remove(data.behaviorsByName[behavior.className])
            });
          }).catch(error => {
            Ana.fail("analyzer/analyze", mainHtmlPath, error);
          });
        })
Exemplo n.º 2
0
async function main() {
  const rootDir = process.argv[2];
  const isInTests = /(\b|\/|\\)(test)(\/|\\)/;

  const analyzer = new Analyzer({
    urlLoader : new FsUrlLoader(rootDir),
    urlResolver : new PackageUrlResolver({packageDir : rootDir}),
  });
  const globs = ['*.js', 'lib/**/*'].map(f => path.join(rootDir, f));
  const inputs = (await globby(globs)).filter(f => !f.endsWith('gulpfile.js')).map(f => path.relative(rootDir, f));
  const analysis = await analyzer.analyze(inputs);
  const metadata = generateAnalysis(analysis, analyzer.urlResolver);
  summarizeByFile(metadata);
}
 test('external script tag inlines an es6 module', () => __awaiter(this, void 0, void 0, function* () {
     const root = 'test/html/inline-es6-modules';
     const analyzer = new polymer_analyzer_1.Analyzer({
         urlResolver: new polymer_analyzer_1.FsUrlResolver(root),
         urlLoader: new polymer_analyzer_1.FsUrlLoader(root),
         moduleResolution: 'node',
     });
     const bundler = new bundler_1.Bundler({ analyzer });
     const externalScriptToNodeModuleUrl = analyzer.resolveUrl('external-script-to-node-module.html');
     const { documents } = yield bundler.bundle(yield bundler.generateManifest([externalScriptToNodeModuleUrl]));
     const externalScriptToNodeModuleDoc = documents.getHtmlDoc(externalScriptToNodeModuleUrl);
     assert.deepEqual(externalScriptToNodeModuleDoc.content, test_utils_1.heredoc `
   <script type="module">
   const feature = {
     cool: 'thing'
   };
   console.log('imported some-package/main.js');
   </script>
 `);
 }));
Exemplo n.º 4
0
function runAnalyzer() {
  console.log('Done.');

  const isInTests = /(\b|\/|\\)(test)(\/|\\)/;
  const isNotTest = (f) =>!f.sourceRange || (!isInTests.test(f.sourceRange.file) && !f.sourceRange.file.endsWith('gulpfile.js'));

  const rootDir = path.resolve('temp');
  const analyzer = new Analyzer({
    urlLoader: new FsUrlLoader(rootDir),
    urlResolver: new PackageUrlResolver({packageDir: rootDir}),
  });

  analyzer.analyzePackage()
    .then((_package) => {
      console.log('Analyzer done');
      const metadata = generateAnalysis(
        _package, analyzer.urlResolver, isNotTest);
      const json = JSON.stringify(metadata, null, 2);
      fs.writeFileSync('polymer2_analysis.json', json);

      function generateNamespace(namespace) {
        console.log(`generating namespace ${namespace && namespace.name}`);

        const overview = {
          name: namespace.name,
          description: namespace.description,
          summary: namespace.summary,
          namespaces: [],
          elements: [],
          classes: [],
          mixins: [],
          behaviors: [],
          functions: namespace.functions, // already summarized
        };

        console.log(`Processing ${namespace.elements && namespace.elements.length} elements`);
        if (namespace.elements) {
          for (const element of namespace.elements) {
            console.log(`adding ${getElementName(element)} to ${namespace.name}`);
            const summary = {
              name: element.name,
              tagname: element.tagname,
              summary: element.summary,
            };
            overview.elements.push(summary);
            const fileContents = elementPage(element);
            const filename = path.join(apiDocsPath, getElementUrl(element) + '.html');
            console.log('Writing', filename);
            fs.writeFileSync(filename, fileContents);
          }
        }

        console.log(`Processing ${namespace.classes && namespace.classes.length} classes`);
        if (namespace.classes) {
          for (const klass of namespace.classes) {
            if (!klass.name) {
              continue;
            }
            console.log(`adding ${klass.name} to ${namespace.name}`);
            const summary = {
              name: klass.name,
              summary: klass.summary,
            };
            overview.classes.push(summary);
            const fileContents = classPage(klass);
            const filename = path.join(apiDocsPath, getClassUrl(klass) + '.html');
            console.log('Writing', filename);
            fs.writeFileSync(filename, fileContents);
          }
        }

        console.log(`Processing ${namespace.mixins && namespace.mixins.length} mixins`);
        if (namespace.mixins) {
          for (const mixin of namespace.mixins) {
            console.log(`adding ${mixin.name} to ${namespace.name}`);
            const summary = {
              name: mixin.name,
              summary: mixin.summary,
            };
            overview.mixins.push(summary);

            const fileContents = mixinPage(mixin);
            const filename = path.join(apiDocsPath, getMixinUrl(mixin) + '.html');
            console.log('Writing', filename);
            fs.writeFileSync(filename, fileContents);
          }
        }

        // TODO(justinfagnani): behaviors

        console.log(`Processing ${namespace.namespaces && namespace.namespaces.length} namespaces`);
        if (namespace.namespaces) {
          for (const nestedNamespace of namespace.namespaces) {
            console.log(`adding ${nestedNamespace.name} to ${namespace.name}`);
            const summary = {
              name: nestedNamespace.name,
              summary: nestedNamespace.summary,
            };
            overview.namespaces.push(summary);
            generateNamespace(nestedNamespace);
          }
        }

        if (namespace.name) {
          const fileContents = namespacePage(overview);
          let filename;
          if (namespace.name === 'Polymer') {
            filename = 'index.html';
          } else {
            filename = getNamespaceUrl(namespace) + '.html';
          }
          const filepath = path.join(apiDocsPath, filename);
          console.log('Writing', filepath);
          fs.writeFileSync(filepath, fileContents);
        }
      }

      fs.mkdirSync(path.join(apiDocsPath, 'elements'));
      fs.mkdirSync(path.join(apiDocsPath, 'classes'));
      fs.mkdirSync(path.join(apiDocsPath, 'mixins'));
      fs.mkdirSync(path.join(apiDocsPath, 'namespaces'));

      // We know we just have 1 namespace: Polymer
      generateNamespace(metadata.namespaces[0]);

      cleanUp(function() {
        console.log('Done.');
        console.log('\nAPI docs completed with great success');
      });
    }, (e) => {
      console.error('Error running analyzePackage()', e);
    });
}
Exemplo n.º 5
0
async function polymerCssBuild(paths, options = {}) {
  const nativeShadow = options ? !options['build-for-shady'] : true;
  const polymerVersion = options['polymer-version'] || 2;
  const customStyleMatch = polymerVersion === 2 ? customStyleMatchV2 : customStyleMatchV1;
  setUpLibraries(nativeShadow);
  // build analyzer loader
  const loader = new InMemoryOverlayUrlLoader();
  const analyzer = new Analyzer({
    urlLoader: loader,
    parsers: createParserMap(),
    scanners: createScannerMap(polymerVersion === 2)
  });
  // load given files as strings
  paths.forEach((p) => {
    loader.urlContentsMap.set(analyzer.resolveUrl(p.url), p.content);
  });
  // run analyzer on all given files
  /** @type {Analysis} */
  const analysis = await analyzer.analyze(paths.map((p) => p.url));
  // populate the dom module map
  const domModuleSet = analysis.getFeatures({kind: 'dom-module'})
  for (const domModule of domModuleSet) {
    const scope = domModule.id.toLowerCase();
    const astNode = getAstNode(domModule);
    domModuleMap[scope] = astNode;
    setNodeFileLocation(astNode, domModule);
  }
  // grap a set of all inline html documents to update at the end
  const inlineHTMLDocumentSet = buildInlineDocumentSet(analysis);
  // map polymer elements to styles
  const moduleStyles = [];
  for (const polymerElement of getOrderedPolymerElements(analysis)) {
    const scope = polymerElement.tagName;
    let styles = [];
    if (!polymerElement.domModule) {
      // there can be cases where a polymerElement is defined in a way that
      // analyzer can't get associate it with the <dom-module>, so try to find
      // it before assuming the polymerElement has an inline template
      findDisconnectedDomModule(polymerElement, analysis);
    }
    if (polymerElement.domModule) {
      const domModule = polymerElement.domModule;
      markDomModule(domModule, scope, nativeShadow, polymerVersion > 1);
      styles = getAndFixDomModuleStyles(domModule);
    } else {
      markPolymerElement(polymerElement, nativeShadow, analysis);
      styles = getInlinedStyles(polymerElement, analysis);
    }
    styles.forEach((s) => {
      scopeMap.set(s, scope);
      setNodeFileLocation(s, polymerElement);
    });
    moduleStyles.push(styles);
  }
  // also process dom modules used only for style sharing
  for (const domModule of domModuleSet) {
    const {id} = domModule;
    const domModuleIsElementTemplate = analysis.getFeatures({kind: 'polymer-element', id}).size > 0;
    if (!domModuleIsElementTemplate) {
      const styles = getAndFixDomModuleStyles(domModuleMap[id]);
      styles.forEach((s) => {
        scopeMap.set(s, id);
        setNodeFileLocation(s, domModule);
      });
      moduleStyles.push(styles);
    }
  }
  // inline and flatten styles into a single list
  const flatStyles = [];
  moduleStyles.forEach((styles) => {
    if (!styles.length) {
      return;
    }
    // do style includes
    if (options ? !options['no-inline-includes'] : true) {
      styles.forEach((s) => inlineStyleIncludes(s, nativeShadow));
    }
    // reduce styles to one
    const finalStyle = styles[styles.length - 1];
    dom5.setAttribute(finalStyle, 'scope', scopeMap.get(finalStyle));
    if (styles.length > 1) {
      const consumed = styles.slice(0, -1);
      const text = styles.map((s) => dom5.getTextContent(s));
      const includes = styles.map((s) => getAttributeArray(s, 'include')).reduce((acc, inc) => acc.concat(inc));
      consumed.forEach((c) => dom5.remove(c));
      dom5.setTextContent(finalStyle, text.join(''));
      const oldInclude = getAttributeArray(finalStyle, 'include');
      const newInclude = Array.from(new Set(oldInclude.concat(includes))).join(' ');
      if (newInclude) {
        dom5.setAttribute(finalStyle, 'include', newInclude);
      }
    }
    flatStyles.push(finalStyle);
  });
  // find custom styles
  const customStyles = nodeWalkAllDocuments(analysis, customStyleMatch);
  // inline custom styles with includes
  if (options ? !options['no-inline-includes'] : true) {
    customStyles.forEach((s) => inlineStyleIncludes(s, nativeShadow));
  }
  // add custom styles to the front
  // custom styles may define mixins for the whole tree
  flatStyles.unshift(...customStyles);
  // fix old `var(--a, --b)` syntax in polymer v1 builds
  if (polymerVersion === 1) {
    flatStyles.forEach((s) => {
      const text = dom5.getTextContent(s);
      const ast = CssParse.parse(text);
      StyleUtil.forEachRule(ast, (rule) => {
        fixBadVars(rule);
      });
      dom5.setTextContent(s, CssParse.stringify(ast, true));
    });
  }
  // populate mixin map
  flatStyles.forEach((s) => {
    const text = dom5.getTextContent(s);
    const ast = CssParse.parse(text);
    applyShim(ast);
  });
  // parse, transform, emit
  flatStyles.forEach((s) => {
    let text = dom5.getTextContent(s);
    const ast = CssParse.parse(text);
    if (customStyleMatch(s)) {
      // custom-style `:root` selectors need to be processed to `html`
      StyleUtil.forEachRule(ast, (rule) => {
        if (options && options['build-for-shady']) {
          StyleTransformer.documentRule(rule);
        } else {
          StyleTransformer.normalizeRootSelector(rule);
        }
      });
      // mark the style as built
      markElement(s, nativeShadow);
    }
    applyShim(ast);
    if (nativeShadow) {
      dirTransform(ast, polymerVersion);
      if (polymerVersion === 1) {
        slottedTransform(ast);
      }
    } else {
      shadyShim(ast, s, analysis);
      if (polymerVersion === 1) {
        contentTransform(ast, scopeMap.get(s));
      }
    }
    text = CssParse.stringify(ast, true);
    dom5.setTextContent(s, text);
  });
  // update inline HTML documents
  for (const inlineDocument of inlineHTMLDocumentSet) {
    updateInlineDocument(inlineDocument);
  }
  return paths.map((p) => {
    const doc = getDocument(analysis, p.url);
    return {
      url: p.url,
      content: doc.stringify()
    };
  });
}