diff --git a/docs/release-notes/images/CustomMimeTypeSearch.png b/docs/release-notes/images/CustomMimeTypeSearch.png new file mode 100644 index 0000000000..5e70a1b607 Binary files /dev/null and b/docs/release-notes/images/CustomMimeTypeSearch.png differ diff --git a/docs/release-notes/images/RandoInputWithCustomResult.gif b/docs/release-notes/images/RandoInputWithCustomResult.gif new file mode 100644 index 0000000000..69dcc974b3 Binary files /dev/null and b/docs/release-notes/images/RandoInputWithCustomResult.gif differ diff --git a/docs/release-notes/images/Screen+Shot+2017-09-05+at+11.31.50.png b/docs/release-notes/images/Screen+Shot+2017-09-05+at+11.31.50.png new file mode 100644 index 0000000000..9cf17d91ae Binary files /dev/null and b/docs/release-notes/images/Screen+Shot+2017-09-05+at+11.31.50.png differ diff --git a/docs/release-notes/images/Screen+Shot+2017-09-05+at+11.38.58.png b/docs/release-notes/images/Screen+Shot+2017-09-05+at+11.38.58.png new file mode 100644 index 0000000000..418298212b Binary files /dev/null and b/docs/release-notes/images/Screen+Shot+2017-09-05+at+11.38.58.png differ diff --git a/docs/release-notes/images/Screen+Shot+2017-09-05+at+16.21.35.png b/docs/release-notes/images/Screen+Shot+2017-09-05+at+16.21.35.png new file mode 100644 index 0000000000..6ed104b5ad Binary files /dev/null and b/docs/release-notes/images/Screen+Shot+2017-09-05+at+16.21.35.png differ diff --git a/docs/release-notes/images/adf-process-instance-header-attachment.png b/docs/release-notes/images/adf-process-instance-header-attachment.png new file mode 100644 index 0000000000..c6a876471a Binary files /dev/null and b/docs/release-notes/images/adf-process-instance-header-attachment.png differ diff --git a/docs/release-notes/images/bundle+size+check.png b/docs/release-notes/images/bundle+size+check.png new file mode 100644 index 0000000000..9828842a43 Binary files /dev/null and b/docs/release-notes/images/bundle+size+check.png differ diff --git a/docs/release-notes/images/copy-and-move-II.gif b/docs/release-notes/images/copy-and-move-II.gif new file mode 100644 index 0000000000..d109140321 Binary files /dev/null and b/docs/release-notes/images/copy-and-move-II.gif differ diff --git a/docs/release-notes/images/form-style-sample.png b/docs/release-notes/images/form-style-sample.png new file mode 100644 index 0000000000..7ed73bf299 Binary files /dev/null and b/docs/release-notes/images/form-style-sample.png differ diff --git a/docs/release-notes/images/info-drawer.gif b/docs/release-notes/images/info-drawer.gif new file mode 100644 index 0000000000..83b451a8f1 Binary files /dev/null and b/docs/release-notes/images/info-drawer.gif differ diff --git a/docs/release-notes/images/security+check.png b/docs/release-notes/images/security+check.png new file mode 100644 index 0000000000..0f35112be5 Binary files /dev/null and b/docs/release-notes/images/security+check.png differ diff --git a/docs/release-notes/images/toobar.gif b/docs/release-notes/images/toobar.gif new file mode 100644 index 0000000000..57d26ff06f Binary files /dev/null and b/docs/release-notes/images/toobar.gif differ diff --git a/tools/doc/tools/fileChecker.js b/tools/doc/tools/fileChecker.js index 16289940cc..96114c7a0f 100644 --- a/tools/doc/tools/fileChecker.js +++ b/tools/doc/tools/fileChecker.js @@ -3,14 +3,19 @@ Object.defineProperty(exports, "__esModule", { value: true }); var path = require("path"); var fs = require("fs"); var unist_util_select_1 = require("unist-util-select"); +var lev = require("fast-levenshtein"); var ngHelpers = require("../ngHelpers"); -//const angFilenameRegex = /([a-zA-Z0-9\-]+)\.((component)|(directive)|(interface)|(model)|(pipe)|(service)|(widget))/; var imageFolderPath = path.resolve('docs', 'docassets', 'images'); +// Using this value for the edit distance between Markdown image URLs +// and filenames is enough to trap errors like missing out the 'images' +// folder in the path. Keeping it low avoids crazy suggestions. +var maxImagePathLevDistance = 7; function processDocs(mdCache, aggData, errorMessages) { var pathnames = Object.keys(mdCache); var classlessDocs = []; var linkRefs = {}; var imageRefs = {}; + var brokenImageRefs = {}; var filters = makeFilepathFilters(aggData.config["fileCheckerFilter"]); pathnames.forEach(function (pathname) { var fileBaseName = path.basename(pathname, '.md'); @@ -26,22 +31,15 @@ function processDocs(mdCache, aggData, errorMessages) { var linkElems = unist_util_select_1.selectAll('link', tree); linkElems.forEach(function (linkElem) { var normUrl = normaliseLinkPath(pathname, linkElem.url); - if (linkRefs[normUrl]) { - linkRefs[normUrl].push(pathname); - } - else { - linkRefs[normUrl] = [pathname]; - } + multiSetAdd(linkRefs, normUrl, pathname); }); } var imageElems = unist_util_select_1.selectAll('image', tree); imageElems.forEach(function (imageElem) { var normUrl = normaliseLinkPath(pathname, imageElem.url); - if (imageRefs[normUrl]) { - imageRefs[normUrl].push(pathname); - } - else { - imageRefs[normUrl] = [pathname]; + multiSetAdd(imageRefs, normUrl, pathname); + if (!fs.existsSync(normUrl)) { + brokenImageRefs[normUrl] = pathname; } }); }); @@ -56,6 +54,7 @@ function processDocs(mdCache, aggData, errorMessages) { } console.groupEnd(); }); + console.log(); var imagePaths = getImagePaths(imageFolderPath); imagePaths.forEach(function (imagePath) { if (!imageRefs[imagePath]) { @@ -63,6 +62,20 @@ function processDocs(mdCache, aggData, errorMessages) { console.log("Warning: no links to image file \"" + relImagePath + "\""); } }); + console.log(); + var brokenImUrls = Object.keys(brokenImageRefs); + brokenImUrls.forEach(function (url) { + var relUrl = url.substring(url.indexOf('docs')); + var relDocPath = brokenImageRefs[url].substring(brokenImageRefs[url].indexOf('docs')); + console.group("Broken image link \"" + relUrl + "\" found in \"" + relDocPath); + imagePaths.forEach(function (imPath) { + if (lev.get(imPath, url) <= maxImagePathLevDistance) { + var relImPath = imPath.substring(imPath.indexOf('docs')); + console.log("Should it be \"" + relImPath + "\"?"); + } + }); + console.groupEnd(); + }); } exports.processDocs = processDocs; function normaliseLinkPath(homeFilePath, linkUrl) { @@ -84,3 +97,11 @@ function filterFilepath(filters, filepath) { } return false; } +function multiSetAdd(container, key, value) { + if (container[key]) { + container[key].push(value); + } + else { + container[key] = [value]; + } +} diff --git a/tools/doc/tools/fileChecker.ts b/tools/doc/tools/fileChecker.ts index b52b2f2cd0..be922b1c8e 100644 --- a/tools/doc/tools/fileChecker.ts +++ b/tools/doc/tools/fileChecker.ts @@ -3,12 +3,19 @@ import * as fs from "fs"; import { select, selectAll } from "unist-util-select"; +import * as lev from "fast-levenshtein"; + import * as ngHelpers from "../ngHelpers"; -//const angFilenameRegex = /([a-zA-Z0-9\-]+)\.((component)|(directive)|(interface)|(model)|(pipe)|(service)|(widget))/; const imageFolderPath = path.resolve('docs', 'docassets', 'images'); +// Using this value for the edit distance between Markdown image URLs +// and filenames is enough to trap errors like missing out the 'images' +// folder in the path. Keeping it low avoids crazy suggestions. +const maxImagePathLevDistance = 7; + + export function processDocs(mdCache, aggData, errorMessages) { var pathnames = Object.keys(mdCache); @@ -16,6 +23,7 @@ export function processDocs(mdCache, aggData, errorMessages) { let classlessDocs = []; let linkRefs = {}; let imageRefs = {}; + let brokenImageRefs = {}; let filters = makeFilepathFilters(aggData.config["fileCheckerFilter"]); @@ -35,12 +43,7 @@ export function processDocs(mdCache, aggData, errorMessages) { linkElems.forEach(linkElem => { let normUrl = normaliseLinkPath(pathname, linkElem.url); - - if (linkRefs[normUrl]) { - linkRefs[normUrl].push(pathname); - } else { - linkRefs[normUrl] = [ pathname ]; - } + multiSetAdd(linkRefs, normUrl, pathname); }); } @@ -48,11 +51,10 @@ export function processDocs(mdCache, aggData, errorMessages) { imageElems.forEach(imageElem => { let normUrl = normaliseLinkPath(pathname, imageElem.url); + multiSetAdd(imageRefs, normUrl, pathname); - if (imageRefs[normUrl]) { - imageRefs[normUrl].push(pathname); - } else { - imageRefs[normUrl] = [ pathname ]; + if (!fs.existsSync(normUrl)) { + brokenImageRefs[normUrl] = pathname; } }); }); @@ -71,6 +73,8 @@ export function processDocs(mdCache, aggData, errorMessages) { console.groupEnd(); }); + console.log(); + let imagePaths = getImagePaths(imageFolderPath); imagePaths.forEach(imagePath => { @@ -79,6 +83,25 @@ export function processDocs(mdCache, aggData, errorMessages) { console.log(`Warning: no links to image file "${relImagePath}"`); } }); + + console.log(); + + let brokenImUrls = Object.keys(brokenImageRefs); + + brokenImUrls.forEach(url => { + let relUrl = url.substring(url.indexOf('docs')); + let relDocPath = brokenImageRefs[url].substring(brokenImageRefs[url].indexOf('docs')); + console.group(`Broken image link "${relUrl}" found in "${relDocPath}`); + + imagePaths.forEach(imPath => { + if (lev.get(imPath, url) <= maxImagePathLevDistance) { + let relImPath = imPath.substring(imPath.indexOf('docs')); + console.log(`Should it be "${relImPath}"?`) + } + }); + + console.groupEnd(); + }); } @@ -106,4 +129,13 @@ function filterFilepath(filters: RegExp[], filepath: string): boolean { } } return false; +} + + +function multiSetAdd(container: {}, key: string, value: string) { + if (container[key]) { + container[key].push(value); + } else { + container[key] = [ value ]; + } } \ No newline at end of file