Best JavaScript code snippet using playwright-internal
marsRev.js
Source:marsRev.js  
1/*2 * grunt-marsRev3 * https://github.com/tdp100/grunt-marsRev4 *5 * Copyright (c) 2015 tangdeping6 * Licensed under the MIT license.7 */8'use strict';9var fs = require('fs');10var path = require('path');11var iconv = require('iconv-lite');12var crypto = require('crypto');13var win_sep = '\\';14var posix_sep = '/';15// The module to be exported.16var deal = function (options, grunt) {17    this.options = grunt.util._.extend({18        hash: {19            algorithm: 'md5',20            inputEncoding: 'utf8',21            length: 422        }23    }, options);24    // The default file encoding to use.25    var defaultEncoding = 'utf8';26    // Whether to preserve the BOM on file.read rather than strip it.27    var preserveBOM = false;28    var pathSeparatorRe = /[\/\\]/g;29    var hashPrefixPatternSource = '([a-zA-Z0-9]{' + this.options.hash.length + '}\\.)?';30    var filePathPattern = new RegExp(hashPrefixPatternSource + '(([\\w\\d-_/.!]+)\\.(\.[0-9a-z]+)$)');31    var dependencyPathPattern = new RegExp('(\'|")[\\w\\d-_/.!\\,\\:\\[\\]]+(\'|")', 'g');32    // e.g. 'app', "controllers/main", "css!/styles/main"33    var definePattern = new RegExp('define\\s*\\(\\s*(' + dependencyPathPattern.source + '\\s*,?\\s*)*\\s*\\[\\s*(' + dependencyPathPattern.source + '\\s*,?\\s*)*\\s*\\]', 'ig');34    // e.g. define("moduleName",["app","controllers/main"]... define(["app","controllers/main"]...35    var requirePattern = new RegExp('(require\\s*\\(\\s*\\[\\s*(' + dependencyPathPattern.source + '\\s*,?\\s*)*\\]\\s*)|(require\\s*\\(\\s*(' + dependencyPathPattern.source + '\\s*,?\\s*)*)', 'ig');36    // e.g. require(['app']... require('app'...37    var dependenciesPattern = new RegExp('(dependencies\\s*(:|=)\\s*\\[\\s*(' + dependencyPathPattern.source + '\\s*,?\\s*)*\\]\\s*)|(dependencies\\s*\\.\\s*push\\(\\s*(' + dependencyPathPattern.source + '\\s*,?\\s*)*)', 'ig');38    // e.g. dependencies: ['css!../~','~']... dependencies = ['css!../~','~']... dependencies.push('~');39    var cssUrlPattern = new RegExp('url\\s*\\(\\s*(' + dependencyPathPattern.source + ')\\s*\\)', 'ig');40    // e.g. url("./fonts/flaticon.svg")  or url('./fonts/flaticon.svg') or url(./fonts/flaticon.svg)41    var resourceUrlPattern = new RegExp('(href|src)\\s*=\\s*(' + dependencyPathPattern.source + ')\\s*', 'ig');42    //以䏿¯å¯¹nezhaæ¡æ¶ä¸çlazy-load/lazyLoad.jså è½½æºå¶ä¸çæä»¶è·¯å¾æ£å表达å¼ç书åï¼ç¨äºæåºåºç¸åºçä¾èµ43    var templateUrlPattern = new RegExp('(\'|")templateUrl(\'|")\\s*:\\s*(' + dependencyPathPattern.source + ')\\s*', 'ig');44    // e.g. templateUrl: "src/app/business/home/views/home.html",45    var directivesPattern = new RegExp('(\'|")directives(\'|")\\s*:\\s*\\[\\s*(' + dependencyPathPattern.source + '\\s*,?\\s*)*\\s*\\]', 'ig');46    // e.g. 'directives': ['app/business/home/controllers/homeCtrl'],47    var servicesPattern = new RegExp('(\'|")services(\'|")\\s*:\\s*\\[\\s*(' + dependencyPathPattern.source + '\\s*,?\\s*)*\\s*\\]', 'ig');48    // e.g. 'services': ['app/business/home/controllers/homeCtrl'],49    var controllersPattern = new RegExp('(\'|")controllers(\'|")\\s*:\\s*\\[\\s*(' + dependencyPathPattern.source + '\\s*,?\\s*)*\\s*\\]', 'ig');50    // e.g. 'controllers': ['app/business/home/controllers/homeCtrl'],51    var factoriesPattern = new RegExp('(\'|")factories(\'|")\\s*:\\s*\\[\\s*(' + dependencyPathPattern.source + '\\s*,?\\s*)*\\s*\\]', 'ig');52    // e.g. 'factories': ['app/business/home/controllers/homeCtrl'],53    var jsPattern = new RegExp('(\'|")js(\'|")\\s*:\\s*\\[\\s*(' + dependencyPathPattern.source + '\\s*,?\\s*)*\\s*\\]', 'ig');54    // e.g. "js": ["tiny-directives/Table"]55    //lazy-load  ç»æ56    //å®ä¹è§åï¼ä¸å¡éè¦ï¼å¨jsä¸å®ä¹çæä»¶è·¯å¾åé57    var fileUrlPattern = new RegExp('(\'|")(url|content)(\'|")\\s*:\\s*(' + dependencyPathPattern.source + ')', 'ig');58    /**59     * å°windowsæ ¼å¼çè·¯å¾è½¬å为linuxæ ¼å¼çè·¯å¾60     * @param pathName  è·¯å¾61     * @returns {*}62     */63    var parseLinuxPath = function (pathName) {64        if (typeof pathName === 'string') {65            return pathName.split(win_sep).join(posix_sep);66        }67        return pathName;68    };69    /**70     * 读åæä»¶å
容71     * @param filepath  æä»¶è·¯å¾72     * @param options   é项ï¼å¯è®¾ç½®encodingæ ¼å¼73     * @returns {*}74     */75    var read = function (filepath, options) {76        if (!options) {77            options = {};78        }79        var contents;80        try {81            contents = fs.readFileSync(String(filepath));82            // If encoding is not explicitly null, convert from encoded buffer to a83            // string. If no encoding was specified, use the default.84            if (options.encoding !== null) {85                contents = iconv.decode(contents, options.encoding || defaultEncoding);86                // Strip any BOM that might exist.87                if (!preserveBOM && contents.charCodeAt(0) === 0xFEFF) {88                    contents = contents.substring(1);89                }90            }91            return contents;92        } catch (e) {93            grunt.fail.warn('Unable to read "' + filepath + '" file (Error code: ' + e.code + ').', e);94        }95    };96    /**97     * åæä»¶98     * @param filepath è·¯å¾99     * @param contents å
容100     * @param options  é项101     * @returns {boolean}102     */103    var write = function (filepath, contents, options) {104        if (!options) {105            options = {};106        }107        // Create path, if necessary.108        mkdir(path.dirname(filepath));109        try {110            // If contents is already a Buffer, don't try to encode it. If no encoding111            // was specified, use the default.112            if (!Buffer.isBuffer(contents)) {113                contents = iconv.encode(contents, options.encoding || defaultEncoding);114            }115            fs.writeFileSync(filepath, contents);116            return true;117        } catch (e) {118            grunt.fail.warn('Unable to write "' + filepath + '" file (Error code: ' + e.code + ').', e);119        }120    };121    var exists = function () {122        var filePath = path.join.apply(path, arguments);123        return fs.existsSync(filePath);124    };125    var mkdir = function (dirpath, mode) {126        // Set directory mode in a strict-mode-friendly way.127        if (mode == null) {128            mode = parseInt('0777', 8) & (~process.umask());129        }130        dirpath.split(pathSeparatorRe).reduce(function (parts, part) {131            parts += part + '/';132            var subpath = path.resolve(parts);133            if (!exists(subpath)) {134                try {135                    fs.mkdirSync(subpath, mode);136                } catch (e) {137                    grunt.fail.warn('Unable to create directory "' + subpath + '" (Error code: ' + e.code + ').', e);138                }139            }140            return parts;141        }, '');142    };143    var getFiles = function (dir, files_) {144        files_ = files_ || [];145        if(fs.existsSync(dir) && fs.statSync(dir).isDirectory()) {146            var files = fs.readdirSync(dir);147            for (var i in files) {148                var name = '';149                if (dir[dir.length - 1] === '/') {150                    name = dir + files[i];151                }152                else {153                    name = dir + posix_sep + files[i];154                }155                getFiles(name, files_);156            }157        } else {158            files_.push(dir);159        }160        return files_;161    };162    /**163     * å¤çrequire.configï¼æ¾å°å
¶ä¸å®ä¹çç¸å¯¹è·¯å¾164     * @param requireJsPath165     * @param dataMainPath166     * @param configFile167     * @returns {*}168     */169    var dealRequireConfig = function (requireJsPath, dataMainPath, configFile) {170        if (dataMainPath === undefined) {171            return path.dirname(requireJsPath);172        }173        var dataMainDir = path.dirname(dataMainPath);174        var contents = read(configFile);175        var configJSON = JSON.parse(contents);176        //å¤çconfig.baseUrl177        var baseUrl = configJSON.baseUrl;178        //åå¹¶è·¯å¾179        baseUrl = path.join(dataMainDir, baseUrl);180        //å¤çconfig.paths181        var paths = {};182        for (var key in configJSON.paths) {183            var standardPath = path.join(baseUrl, configJSON.paths[key]);184            paths[key] = parseLinuxPath(standardPath);185        }186        //å¤çconfig.shim187        var shim = {};188        for (var key in configJSON.shim) {189            var relatePath = path.dirname(key);190            shim[key] = parseLinuxPath(path.join(paths[relatePath], path.basename(key)) + '.js');191            var deps = configJSON.shim[key].deps;192            if (deps === undefined) {193                continue;194            }195            deps.forEach(function (dep) {196                var depRelatePath = path.dirname(dep);197                shim[dep] = parseLinuxPath(path.join(paths[depRelatePath], path.basename(dep)) + '.js');198            });199        }200        var result = {201            'baseUrl': parseLinuxPath(baseUrl),  //ç¨äºå¨requireä¸ä½¿ç¨äºç¸å¯¹è·¯å¾ï¼ä½å´æ²¡æä½¿ç¨config.pathsä¸å®ä¹çç¸å¯¹è·¯å¾202            'paths': paths,203            'shim': shim204        };205        grunt.log.writeln(JSON.stringify(result));206        return result;207    };208    /**209     * è®¡ç®æä»¶çåå¸å¼210     * @param filepath æä»¶è·¯å¾211     * @param fileEncoding æä»¶ç¼ç , é»è®¤utf8212     * @param hashAlgorithm åå¸ç®æ³ï¼é»è®¤md5213     * @returns {*}214     */215    var createHashforFile = function (filepath, fileEncoding, hashAlgorithm) {216        var hash = crypto.createHash(hashAlgorithm);217        hash.update(read(filepath), fileEncoding);218        return hash.digest('hex');219    };220    /**221     * ç»æä»¶éå½åhashåç§°222     * @param targetPath223     * @returns {*}224     */225    this.renameHashNameForFile = function (targetPath) {226        var originName = path.basename(targetPath);227        var hash = createHashforFile(targetPath, this.options.hash.inputEncoding, this.options.hash.algorithm);228        var prefix = hash.slice(0, this.options.hash.length);229        // clear hash prefix from file name230        var filePathMatch = originName.match(filePathPattern);231        if (filePathMatch && filePathMatch[1] && filePathMatch[1].match(/\d/)) {232            originName = filePathMatch[2];233        }234        var targetPathNew = parseLinuxPath(path.join(path.dirname(targetPath), prefix + '.' + originName));235        grunt.log.writeln('Rename ' + targetPath + ' to ' + targetPathNew + '...');236        // rename file (adding hash prefix)237        return this.syncRenameFile(targetPath, prefix);238    };239    /**240     * ä¿®æ¹æä»¶åç§°ï¼è¿éæä¸ä¸ªç¹æ®åºæ¯ï¼ç»i18næä»¶è¿è¡åå¸ï¼ç±äºi18nä¼å¨ææ ¹æ®è¯è¨ä¿¡æ¯å è½½ä¸åçi18næä»¶ï¼æä»¬è¿é约å®hash zhæ¶åæ¥ä¿®æ¹å
¶å®è¯è¨æä»¶åï¼ä¿è¯hash弿¯ä¸æ ·çãè¿ä¸ä¼å½±åå级ï¼åå æ¯å级æ¶ä¸è¬é½ä¼åæ¥åå241     * @param targetPath242     * @param prefix243     * @returns {*}244     */245    this.syncRenameFile = function(targetPath, prefix) {246        var self = this;247        //夿æ¯å¦æ¯i18næä»¶248        var originName = path.basename(targetPath);249        var baseDirName = path.dirname(targetPath);250        var originPath = '';251        var targetPathNew = '';252        var result = [];253        if(/i18n\/.+\/.+/.test(targetPath)) {254            //è·åi18n䏿æçè¯è¨åç®å½255            var files = fs.readdirSync(parseLinuxPath(path.join(baseDirName, '../')));256            console.log("files baseDirName = ", baseDirName);257            console.log(files);258            for (var i = 0; i < files.length; i++) {259                if (fs.statSync(parseLinuxPath(path.join(baseDirName, '../' + files[i]))).isDirectory()) {260                    originPath = parseLinuxPath(path.join(baseDirName, '../' + files[i] + '/' + originName));261                    targetPathNew = parseLinuxPath(path.join(baseDirName, '../' + files[i] + '/' + prefix + '.' + originName));262                    fs.renameSync(originPath, targetPathNew);263                    self.dependenciesMap[originPath].hashFilePath = targetPathNew;264                    result.push({265                        originPath: originPath,266                        hashPath: targetPathNew267                    });268                }269            }270        }271        else {272            targetPathNew = parseLinuxPath(path.join(baseDirName, prefix + '.' + originName));273            fs.renameSync(targetPath, targetPathNew);274            self.dependenciesMap[targetPath].hashFilePath = targetPathNew;275            result.push({276                originPath: targetPath,277                hashPath: targetPathNew278            });279        }280        return result;281    }282    /**283     * ä»fileItemçä¾èµMapä¸æç´¢æ¯å¦ä¾èµäºtargetPathæä»¶284     * @param fileItem285     * @param targetPath286     * @returns {*}287     */288    this.matchPatternFromArray = function (fileItem, targetPath) {289        var dependencies = this.dependenciesMap[fileItem].dependencies;290        for (var i = 0; i < dependencies.length; i++) {291            var item = dependencies[i];292            //å¹é
è·¯å¾ä¸ç第ä¸é¡¹293            var itemArray = item.split('/');294            var dir = itemArray.shift();295            var standardConfigDir = this.config.paths[dir];296            /**297             *  å
夿æ¯å¦ä½¿ç¨äºrequire.jsä¸çconfig.paths ç¸å¯¹è·¯å¾298             */299            if (standardConfigDir !== undefined) {300                var standardDir = parseLinuxPath(path.join(standardConfigDir, itemArray.join('/')));301                var standardPath = parseLinuxPath(path.join(path.dirname(standardDir), path.basename(item)) + '.js');302                if (standardPath === targetPath) {303                    return item;304                }305            }306            /**307             *  夿æ¯ä½¿ç¨äºç¸å¯¹targetPathçç¸å¯¹è·¯å¾308             */309            else {310                var extname = path.extname(item) !== '' ? '' : '.js';311                var needFromCwd = false;312                ////对äºå¨require.jsä¸ç´æ¥ä½¿ç¨äºæ ¹ç®å½ä¸çæä»¶è·¯å¾ï¼å¦fixtures/frameworkFixture.jsï¼éè¦ä»cwdè·¯å¾ç®èµ·313                if (/^\s*\./g.test(item) === false) {314                    needFromCwd = true;315                }316                //ç±äºangularjsä¸çhtmlæä»¶æ¯éç¨$http卿å忥çï¼è䏿¯éè¿è·¯å¾ä¸è½½çãæä»¥å
¶ä¸çç¸å¯¹è·¯å¾ä¸è½ä»¥htmlæä»¶ä½ä¸ºåè317                if (path.extname(fileItem) === '.html' && fileItem !== this.options.require.accessHtml) {318                    needFromCwd = true;319                }320                var standardPath = '';321                if (needFromCwd) {322                    standardPath = parseLinuxPath(path.join(this.options.cwd, item) + extname);323                }324                else {325                    standardPath = parseLinuxPath(path.join(path.dirname(fileItem), item) + extname);326                }327                if (standardPath === targetPath) {328                    return item;329                }330            }331        }332        return null;333    };334    /**335     * æ¿æ¢targetPathå¨å
¶å®æä»¶ä¸è¢«ä¾èµçè·¯å¾, éè¦éåæ¯ä¸ªæä»¶ä¸çä¾èµMap336     * @param targetPath   æä»¶å
¨è·¯å¾337     * @param targetHashPath  æä»¶åå¸å
¨è·¯å¾338     */339    this.replaceDependencyPath = function (targetPath, targetHashPath) {340        //æ¾å°è¯¥æä»¶å¨å
¶å®ä½¿ç¨æä»¶ä¸çä¾èµå表ï¼ç¶åä¿®æ¹ä¾èµäºè¯¥æä»¶çæä»¶å
容341        for (var fileItem in this.dependenciesMap) {342            if (fileItem === targetPath) {343                continue;344            }345            if (/(.js|.css|.html)/.test(path.extname(fileItem)) === false) {346                continue;347            }348            var fileItemObj = this.dependenciesMap[fileItem];349            var dependencyMatch = this.matchPatternFromArray(fileItem, targetPath);350            if (dependencyMatch) {351                grunt.log.writeln('Replace require path for %s with %s ...', fileItem, targetPath);352                var contents = read(fileItemObj.hashFilePath);353                //å¤çè·¯å¾ä»¥./å¼å
³çåºæ¯ï¼path.dirnameä¼å»æåé¢ç./354                var basename = path.basename(targetHashPath);355                if (path.extname(dependencyMatch) !== '.js') {356                    basename = basename.replace('.js', '');357                }358                var replacePath = path.join(path.dirname(dependencyMatch), basename);359                if (/^\s*\.\//g.test(dependencyMatch) === true) {360                    replacePath = './' + replacePath;361                }362                var replacePath = parseLinuxPath(replacePath);363                grunt.log.writeln('in fileItemObj.hashFilePath =%s, replace dependencyMatch=%s to replacePath=%s', fileItemObj.hashFilePath, dependencyMatch, replacePath);364                write(fileItemObj.hashFilePath, contents.replace(365                    new RegExp('("|\')' + '(' + dependencyMatch + ')' + '("|\')', 'ig'),366                    '$1' + replacePath + '$3'367                ));368            }369        }370    };371    /**372     * è·åæ¯ä¸ªæä»¶ä¸çä¾èµMap373     * 1. æærequire ä¾èµ374     * 2. require.configä¾èµ375     * 3. lazy-load ä¾èµ376     * 4. html 䏿æå¾çï¼css, jsä¾èµ377     * 5. js 䏿å®è§åurl: "path" çä¾èµ378     * 6. cssä¸çå¾çï¼å使件ä¾èµ379     */380    this.getDependenciesMap = function () {381        var self = this;382        var targetFiles = this.files;383        var dependenciesMap = {};384        targetFiles.forEach(function (targetPath) {385            grunt.log.writeln('Search Dependencies of targetPath: %s', targetPath);386            var contents = read(targetPath);387            var defineMatches = contents.match(definePattern);388            var requireMatches = contents.match(requirePattern);389            var dependenciesMatches = contents.match(dependenciesPattern);390            grunt.log.writeln('Define matches: %s', defineMatches);391            grunt.log.writeln('Require matches: %s', requireMatches);392            grunt.log.writeln('Dependencies matches: %s', dependenciesMatches);393            // dependency path array394            var dependencies = [];395            if (/(.js|.css|.html)/.test(path.extname(targetPath)) === true) {396                if (defineMatches) {397                    defineMatches.forEach(function (defineMatch) {398                        var pathMatches = defineMatch.match(dependencyPathPattern);399                        if (pathMatches) {400                            dependencies = dependencies.concat(pathMatches);401                        }402                    });403                }404                if (requireMatches) {405                    requireMatches.forEach(function (requireMatch) {406                        var pathMatches = requireMatch.match(dependencyPathPattern);407                        if (pathMatches) {408                            dependencies = dependencies.concat(pathMatches);409                        }410                    });411                }412                if (dependenciesMatches) {413                    dependenciesMatches.forEach(function (dependenciesMatch) {414                        var pathMatches = dependenciesMatch.match(dependencyPathPattern);415                        if (pathMatches) {416                            dependencies = dependencies.concat(pathMatches);417                        }418                    });419                }420                //妿æ¯main.jsä¸çrequire.configé
ç½®äºshim421                if (targetPath === self.options.require.dataMainPath) {422                    for (var key in self.config.shim) {423                        dependencies = dependencies.concat(key);424                    }425                }426                //妿æ¯.jsæä»¶ï¼éè¦å¤ææ¯ä¸æ¯RouterConfig.js䏿¯å¦ä½¿ç¨äºlazy-loadæºå¶å¹é
äºè¦å è½½çæä»¶427                if (path.extname(targetPath) === '.js' && /RouterConfig/.test(targetPath)) {428                    var templateUrlMatches = contents.match(templateUrlPattern);429                    grunt.log.writeln('templateUrl matches: %s', templateUrlMatches);430                    if (templateUrlMatches) {431                        templateUrlMatches.forEach(function (templateUrlMatch) {432                            var pathMatches = templateUrlMatch.match(dependencyPathPattern);433                            dependencies = dependencies.concat(pathMatches);434                        });435                    }436                    var directivesMatches = contents.match(directivesPattern);437                    grunt.log.writeln('directives matches: %s', directivesMatches);438                    if (directivesMatches) {439                        directivesMatches.forEach(function (directivesMatch) {440                            var pathMatches = directivesMatch.match(dependencyPathPattern);441                            if (pathMatches) {442                                dependencies = dependencies.concat(pathMatches);443                            }444                        });445                    }446                    var servicesMatches = contents.match(servicesPattern);447                    grunt.log.writeln('services matches: %s', servicesMatches);448                    if (servicesMatches) {449                        servicesMatches.forEach(function (servicesMatch) {450                            var pathMatches = servicesMatch.match(dependencyPathPattern);451                            if (pathMatches) {452                                dependencies = dependencies.concat(pathMatches);453                            }454                        });455                    }456                    var controllersMatches = contents.match(controllersPattern);457                    grunt.log.writeln('controllers matches: %s', controllersMatches);458                    if (controllersMatches) {459                        controllersMatches.forEach(function (controllersMatch) {460                            var pathMatches = controllersMatch.match(dependencyPathPattern);461                            if (pathMatches) {462                                dependencies = dependencies.concat(pathMatches);463                            }464                        });465                    }466                    var factoriesMatches = contents.match(factoriesPattern);467                    grunt.log.writeln('factories matches: %s', factoriesMatches);468                    if (factoriesMatches) {469                        factoriesMatches.forEach(function (factoriesMatch) {470                            var pathMatches = factoriesMatch.match(dependencyPathPattern);471                            if (pathMatches) {472                                dependencies = dependencies.concat(pathMatches);473                            }474                        });475                    }476                    var jsMatches = contents.match(jsPattern);477                    grunt.log.writeln('js matches: %s', jsMatches);478                    if (jsMatches) {479                        jsMatches.forEach(function (jsMatch) {480                            var pathMatches = jsMatch.match(dependencyPathPattern);481                            if (pathMatches) {482                                dependencies = dependencies.concat(pathMatches);483                            }484                        });485                    }486                }487                if (path.extname(targetPath) === '.js') {488                    var fileUrlMatches = contents.match(fileUrlPattern);489                    grunt.log.writeln('fileUrl matches: %s', fileUrlMatches);490                    if (fileUrlMatches) {491                        fileUrlMatches.forEach(function (fileUrlMatch) {492                            var pathMatches = fileUrlMatch.match(dependencyPathPattern);493                            if (pathMatches) {494                                dependencies = dependencies.concat(pathMatches);495                            }496                        });497                    }498                }499                //妿æ¯.js,.html,.cssæä»¶ï¼éè¦è®°å½è¯¥cssæä»¶ä¸å¨æå¼å
¥çå¾çåå符æä»¶500                //注æå¦ææ¯.jsä¸å¼å
¥çcssæ ·å¼ä¸æå¾çä¾èµï¼é£ä¹è·¯å¾å¿
é¡»æ¯ä»¥æ ¹ç®å½ä¸çåç®å½ä¸ºèµ·å§è·¯å¾501                //e.g: $('<div>').css({"background": "#aaaaaa url('theme/default/images/mask-cover.png') 50% 50% repeat-x"});502                //ä¸è½æ¯e.g: $('<div>').css({"background": "#aaaaaa url('./theme/default/images/mask-cover.png') 50% 50% repeat-x"});503                if (/(.js|.css|.html|)/.test(path.extname(targetPath)) === true) {504                    var urlMatches = contents.match(cssUrlPattern);505                    grunt.log.writeln('url matches: %s', urlMatches);506                    if (urlMatches) {507                        urlMatches.forEach(function (urlMatch) {508                            var pathMatches = urlMatch.match(dependencyPathPattern);509                            dependencies = dependencies.concat(pathMatches);510                        });511                    }512                }513                //妿æ¯htmlæä»¶ï¼éè¦è®°å½htmlæä»¶ä¸å¨æå¼å
¥çå¾çåå符æä»¶514                if (path.extname(targetPath) === '.html') {515                    var resourcesMatches = contents.match(resourceUrlPattern);516                    grunt.log.writeln('resources matches: %s', resourcesMatches);517                    if (resourcesMatches) {518                        resourcesMatches.forEach(function (resourceMatch) {519                            var pathMatches = resourceMatch.match(dependencyPathPattern);520                            if (pathMatches) {521                                dependencies = dependencies.concat(pathMatches);522                            }523                        });524                    }525                }526                // remove quotation mark527                for (var i = 0; i < dependencies.length; i++) {528                    dependencies[i] = dependencies[i].replace(/'|"/g, '');529                }530                // remove duplicate dependency path531                for (var i = 0; i < dependencies.length; i++) {532                    var target = dependencies[i];533                    var indexOfNext = dependencies.indexOf(target, i + 1);534                    if (indexOfNext > 0) {535                        dependencies.splice(indexOfNext, 1);536                        i--;537                    }538                }539            }540            dependenciesMap[targetPath] = {};541            dependenciesMap[targetPath].hashFilePath = targetPath;542            dependenciesMap[targetPath].dependencies = dependencies;543        });544        this.dependenciesMap = dependenciesMap;545        console.dir(dependenciesMap);546    };547    /**548     * å¤çéè¦hashçææè·¯å¾549     */550    this.deal = function () {551        var self = this;552        this.config = dealRequireConfig(this.options.require.requireJsPath, this.options.require.dataMainPath, this.options.require.configJSON);553        this.files = getFiles(this.options.cwd);554        this.getDependenciesMap();555        var targetFiles = [];556        var excludeFiles = [];557        this.options.files.forEach(function (filePair) {558            filePair.src.forEach(function (src) {559                if( src && src.indexOf("!") === 0) {560                    src = src.substring(1);561                    getFiles(parseLinuxPath(path.join(self.options.cwd, src)), excludeFiles);562                }563                else {564                    getFiles(parseLinuxPath(path.join(self.options.cwd, src)), targetFiles);565                }566            });567        });568        for(var i=0; i<excludeFiles.length; i++) {569            var target = excludeFiles[i];570            var indexOfNext = targetFiles.indexOf(target);571            if (indexOfNext >= 0) {572                targetFiles.splice(indexOfNext, 1);573            }574        }575        var result = [];576        self.sortTargetFiles(targetFiles, result);577        result.forEach(function (targetFile) {578            var result = self.renameHashNameForFile(targetFile);579            for(var i=0; i< result.length; i++) {580                if(result[i]) {581                    self.replaceDependencyPath(result[i].originPath, result[i].hashPath);582                }583            }584        });585    }586    //æ ¹æ®ä¾èµé¡ºåºè¿è¡æåº587    this.sortTargetFiles = function(targetFiles, result) {588        var flag = false;589        for(var i=0; i<targetFiles.length; i++) {590            if(!this.dependenciesMap[targetFiles[i]] ||591                !this.dependenciesMap[targetFiles[i]].dependencies ||592                this.dependenciesMap[targetFiles[i]].dependencies.length === 0) {593                result.push(targetFiles[i]);594                targetFiles.splice(i, 1);595                i--;596                flag = true;597            } else if(!this.isDependenciesInTargetFiles(targetFiles[i], targetFiles)){598                result.push(targetFiles[i]);599                targetFiles.splice(i, 1);600                i--;601                flag = true;602            }603        }604        if(flag) {605            this.sortTargetFiles(targetFiles, result);606        } else {607            for(var i=0; i<targetFiles.length; i++) {608                result.push(targetFiles[i]);609            }610        }611    }612    this.isDependenciesInTargetFiles = function(fileItem, targetFiles) {613        console.dir(this.files);614        for(var i=0; i<targetFiles.length; i++) {615            var match = this.matchPatternFromArray(fileItem, targetFiles[i]);616            if(match) {617                return true;618            }619        }620        return false;621    }622};623module.exports = function (grunt) {624    // Please see the Grunt documentation for more information regarding task625    // creation: http://gruntjs.com/creating-tasks626    grunt.registerTask('marsRev', 'file hash rename', function () {627        // Merge task-specific and/or target-specific options with these defaults.628        var defaultConfig = {629            'hash': {630                algorithm: 'md5',631                inputEncoding: 'utf8',632                length: 4633            }634        };635        var options = this.options(defaultConfig);636        grunt.log.writeln(JSON.stringify(options));637        if (options.cwd === undefined) {638            grunt.fail.warn("cwd is undefined.");639        }640        var dealInstance = new deal(options, grunt);641        dealInstance.deal();642        grunt.log.ok('success hashed file');643    });...app.js
Source:app.js  
1/**2 * Coder for Raspberry Pi3 * A simple platform for experimenting with web stuff.4 * http://goo.gl/coder5 *6 * Copyright 2013 Google Inc. All Rights Reserved.7 *8 * Licensed under the Apache License, Version 2.0 (the "License");9 * you may not use this file except in compliance with the License.10 * You may obtain a copy of the License at11 *12 *   http://www.apache.org/licenses/LICENSE-2.013 *14 * Unless required by applicable law or agreed to in writing, software15 * distributed under the License is distributed on an "AS IS" BASIS,16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.17 * See the License for the specific language governing permissions and18 * limitations under the License.19 */20var mustache = require('mustache');21var util = require('util');22var fs = require('fs');23exports.settings={};24//These are dynamically updated by the runtime25//settings.appname - the app id (folder) where your app is installed26//settings.viewpath - prefix to where your view html files are located27//settings.staticurl - base url path to static assets /static/apps/appname28//settings.appurl - base url path to this app /app/appname29exports.get_routes = [30        { path:'/', handler:'index_handler'},31        { path: /^\/edit\/(\w+)$/, handler:'index_handler'},32        { path: /^\/api\/getcode\/(\w+)$/, handler:'api_getcode_handler'},33        { path: /^\/api\/media\/list\/(\w+)$/, handler:'api_media_list_handler'},34        { path: /^\/api\/metadata\/get\/(\w+)$/, handler:'api_metadata_get_handler'},35];36exports.post_routes = [37        { path: /^\/api\/savecode\/(\w+)$/, handler:'api_savecode_handler'},38        { path: /^\/api\/savesettings\/(\w+)$/, handler:'api_savesettings_handler'},39        { path: '/api/media/upload', handler:'api_media_upload_handler' },40        { path: '/api/media/remove', handler:'api_media_remove_handler' },41];42exports.index_handler = function( req, res, pathmatches ) {43    var tmplvars = {};44    tmplvars['static_url'] = exports.settings.staticurl;45    tmplvars['app_name'] = exports.settings.appname;46    tmplvars['app_url'] = exports.settings.appurl;47    48    var edit_appname;49    if ( pathmatches && pathmatches[1] != "" ) {50        tmplvars['edit_app_name'] = pathmatches[1];51    } else {52        //TODO: error53        res.end();54        return;55    }56    res.render( exports.settings.viewpath + '/index', tmplvars );57};58exports.api_metadata_get_handler = function( req, res, pathmatches ) {59    var apptoedit = "";60    if ( pathmatches && pathmatches[1] != "" ) {61        apptoedit = pathmatches[1];62    } else {63        //TODO: error64        return;65    }66    67    res.json({68        appname: apptoedit,69        metadata: getMetaInfo( apptoedit )70    });71};72exports.api_getcode_handler = function( req, res, pathmatches ) {73    var path = process.cwd(); //root application path. different from __dirname74    var apptoedit = "";75    if ( pathmatches && pathmatches[1] != "" ) {76        apptoedit = pathmatches[1];77    } else {78        //TODO: error79        return;80    }81    var outdata = {82        htmldata: getFile( path + '/views/apps/' + apptoedit + '/index.html' ),83        jsdata:  getFile(  path + '/static/apps/' + apptoedit + '/js/index.js' ),84        cssdata: getFile( path + '/static/apps/' + apptoedit + '/css/index.css' ),85        appdata: getFile( path + '/apps/' + apptoedit + '/app.js' )86    };87    res.json( outdata );88};89exports.api_media_list_handler = function( req, res, pathmatches ) {90    media = exports.listMedia( pathmatches[1] );91    res.json({ media: media });92};93exports.api_media_remove_handler = function( req, res ) {94    95    var appname = req.param('appname');96    if ( !appname || appname === "" || !appname.match(/^(\w+)$/) ) {97        res.json( {status: 'error', error: "bad app name" } );98        return;99    }100    var fname = req.param('filename');101    if ( !fname || fname === "" || fname === "." || fname === ".." || !fname.match(/^([\w_\-\.])*$/) ) {102        res.json( {status: 'error', error: "bad file name" } );103        return;104    }105    106    var fpath = process.cwd() + '/static/apps/' + appname + '/media/' + fname;107    util.log("MEDIA DELETE: " + fpath );108    err = fs.unlinkSync( fpath );109    if ( !err ) {110        res.json( {status: 'success'} );111    } else {112        res.json( {status: 'error', error: "couldn't delete file"} );113    }114};115exports.api_media_upload_handler = function( req, res ) {116    117    var appname = req.param('appname');118    if ( !appname || appname === "" || !appname.match(/^(\w+)$/) ) {119        res.json( {status: 'error', error: "bad app name" } );120        return;121    }122    if ( req.files && req.files['mediaUpload'] ) {123        var file = req.files.mediaUpload;124        var fname = file.name;125        fname = fname.substr( fname.lastIndexOf('/') + 1);126        fname = fname.replace(/[^\w_\-\.]/g, "_");127        128        if ( fname && fname != "" && fname != "." && fname != ".." ) {129            fs.readFile(file.path, function (err, data) {130                if ( err ) {131                    res.json( {status: 'error', error: "couldn't read file"} );132                    return;133                }134                var path = process.cwd() + '/static/apps/' + appname + '/media/' + fname;135                fs.writeFile(path, data, function (err) {136                    if ( !err ) {137                        res.json({ 138                            status: 'success',139                            filename: fname140                        });141                    } else {142                        res.json( {status: 'error', error: "couldn't save file"} );143                        return;144                    }145                });146            });147        } else {148            res.json( {status: 'error', error: "bad filename"} );149            return;150        }151    } else {152        res.json( {status: 'error', error: "missing attachment" } );153        return;154    }155};156exports.api_savecode_handler = function( req, res, pathmatches ) {157    var path = process.cwd();158    var apptoedit = "";159    if ( pathmatches && pathmatches[1] != "" ) {160        apptoedit = pathmatches[1];161    } else {162        //TODO: error163        return;164    }165    try {166        var datatype = req.param('type');167        var data = req.param('data');168        var err = "";169        170        var metainfo = getMetaInfo(apptoedit);171        try {172            metainfo.modified = getDateString( new Date() );173            //??anything to update from this??174            //var metadata = JSON.parse(req.param('metadata'));175            176        } catch( e ) {177        }178                179        if ( datatype === 'css' ) {180            err = fs.writeFileSync( path + '/static/apps/' + apptoedit + '/css/index.css', data, 'utf8' );181        } else if ( datatype === 'html' ) {182            err = fs.writeFileSync( path + '/views/apps/' + apptoedit + '/index.html', data, 'utf8' );183        } else if ( datatype === 'js' ) {184            err = fs.writeFileSync( path + '/static/apps/' + apptoedit + '/js/index.js', data, 'utf8' );185        } else if ( datatype === 'app' ) {186            err = fs.writeFileSync( path + '/apps/' + apptoedit + '/app.js', data, 'utf8' );187        }188        if ( err && err !== "" ) {189            res.json({190                result: "error",191                type: datatype,192                data: data,193                metadata: metainfo,194                error: err195            });196        }197        198        199        err = fs.writeFileSync( path + '/apps/' + apptoedit + '/meta.json', JSON.stringify(metainfo, null, 4), 'utf8' );200        201        202        if ( err && err !== "" ) {203            res.json({204                result: "metadata error",205                type: datatype,206                data: data,207                metadata: metainfo,208                error: err209            });210        } else {211            res.json({212                result: "saved",213                type: datatype,214                data: data,215                metadata: metainfo,216            });217            218            util.log('app: ' + apptoedit + ' saved. flushing cache.');219            //flush app from cache220            var cached = require.cache[path + '/apps/' + apptoedit + '/app.js'];221            if ( cached ) {222                var theapp = require(path + '/apps/' + apptoedit + '/app');223                if ( theapp.on_destroy ) {224                    theapp.on_destroy();225                }226                delete require.cache[path + '/apps/' + apptoedit + '/app.js'];227            }228        }229                230    } catch ( e ) {231        res.json({232            result: "error saving"233        });234    }   235            236};237exports.api_savesettings_handler = function( req, res, pathmatches ) {238    var path = process.cwd();239    var apptoedit = "";240    if ( pathmatches && pathmatches[1] != "" ) {241        apptoedit = pathmatches[1];242    } else {243        //TODO: error244        return;245    }246    247    var metadata = getMetaInfo( apptoedit );248    var newmetadata = JSON.parse(req.param('metadata'));249    var idchanged = (metadata.name !== newmetadata.name);250    var newappid = apptoedit;251    if ( idchanged ) {252        util.log( "Name Change: " + newmetadata.name );253        newappid = newmetadata.name.toLowerCase();254        newappid = newappid.replace(/\./g, "_");255        newappid = newappid.replace(/[^\w]/g, "_");256        newappid = newappid.replace(/_+/g, "_");257        258        if ( newappid === apptoedit ) {259            idchanged = false;260        } else {261            //this is a real id change262            var idavailable = false;263            var iteration = 0;264            var appdir = process.cwd() + "/apps/";265            var allfiles = fs.readdirSync(appdir);266            while ( !idavailable ) {267                var potential = newappid;268                if ( iteration > 0 ) {269                    potential = potential + '_' + iteration;270                }271                if ( allfiles.indexOf( potential ) >= 0 ) {272                    iteration++;273                } else {274                    newappid = potential;275                    idavailable = true;276                }277            }278        }279    }280    metadata.modified = getDateString( new Date() );281    metadata.color = newmetadata.color;282    metadata.author = newmetadata.author;283    metadata.name = newmetadata.name;284    err = fs.writeFileSync( path + '/apps/' + apptoedit + '/meta.json', JSON.stringify(metadata, null, 4), 'utf8' );285    if ( idchanged && newappid !== "" ) {286        util.log( "APP RENAME: " + apptoedit + " > " + newappid);287        moveProject( apptoedit, newappid );288    }289    res.json({290        metadata: metadata,291        appname: newappid292    });293};294exports.listMedia = function( appname ) {295    var path = process.cwd(); //root application path. different from __dirname296    var mediadir = path + "/static/apps/" + appname + "/media/";297    var media = {};298    var files = fs.readdirSync(mediadir);299    for ( var x in files ) {300        var filename = files[x];301        var info = fs.statSync( mediadir + filename );302        if ( typeof info !== 'undefined' && info && info.isFile() && filename !== '.gitignore' ) {303            var metainfo = {304                created: getDateString( info.mtime ),305                size: info.size,306            };307            308            media[filename] = { filename: filename, metadata: metainfo };309        }310    }311    return media;312};313var moveProject = function( fromid, toid ) {314    var path = process.cwd();315    fs.renameSync( path + "/apps/" + fromid, path + "/apps/" + toid );316    fs.renameSync( path + "/static/apps/" + fromid, path + "/static/apps/" + toid );317    fs.renameSync( path + "/views/apps/" + fromid, path + "/views/apps/" + toid );318};319var getMetaInfo = function( appname ) {320    var appdir = process.cwd() + "/apps/" + appname;321    var metainfo = {322        created: getDateString( new Date() ),323        modified: getDateString( new Date() ),324        color: "#66ddaa",325        author: "",326        name: "",327        hidden: false,328    };329    try {330        metafile = JSON.parse(fs.readFileSync( appdir + "/meta.json", 'utf-8' ));331        metainfo.created = metafile.created;332        metainfo.modified = metafile.modified;333        metainfo.color = metafile.color ? metafile.color : metainfo.color;334        metainfo.author = metafile.author ? metafile.author : metainfo.author;335        metainfo.name = metafile.name ? metafile.name : metainfo.name;336        metainfo.hidden = (typeof metafile.hidden !== 'undefined') ? metafile.hidden : metainfo.hidden;337    } catch( e ) {338    }339    return metainfo;340};341var getFile = function( fpath ) {342    try {343        return fs.readFileSync( fpath, 'utf8' );344    } catch (e) {345        return "";346    }347};348var getDateString = function( d ) {349    var now = new Date();350    var twodigits = function( x ) {351        return x<10 ? '0' + x: x;352    };353    return d.getFullYear() + "-" + twodigits(d.getMonth()+1) + '-' + twodigits(d.getDate());...identities.js
Source:identities.js  
1// All of our identity services and matchers are defined here.2// identityMatchers is used to generate our declarative page match rules, but3// also used to check for matches at runtime for each `service` that we4// support. They have the following schema:5// {6//  "service": Service name, if you add one here update `profileInject` in7//  `identities.js` and `User.prototype.href to fully register it.8//9//  "getUsername": Function to parse the username from the browser10//  `location` object.11//12//  "pathMatches": A regular expression used to match the pathname  within the13//  service (i.e. news.ycombinator.com/user?id=username matches but not14//  news.ycombinator.com/newest).15//16//  "originAndPathMatches": A re2 style regex used to match a page within17//  the service for declarativeContent matching18//  (https://developer.chrome.com/extensions/declarativeContent).19//20//  "subdomains": Subdomains that the host is considered valid on.21//22//  "host": Used to match that the host is the host we want to run on23//  (preventing any regex trickery for `pathMatches` or24//  `originAndPathMatches`).25//26//  "css": (optional) CSS selector which must be present for declarativeContent27//  or the chat button to be injected.28//29// }30//31const identityMatchers = [32  {33    service: "keybase",34    getUsername: function(loc) { return loc.pathname.split('/')[1]; },35    pathMatches: new RegExp('^/([\\w]+)[/]?$'),36    originAndPathMatches: '^https://keybase\\.io/[\\w]+[/]?$',37    subdomains: [],38    host: 'keybase.io',39    css: ['.profile-heading']40  },41  {42    service: "reddit",43    getUsername: function(loc) { return loc.pathname.split('/')[2]; },44    pathMatches: new RegExp('^/user/([\\w-]+)[/]?$'),45    originAndPathMatches: '^https://[\\w.-]*?\\.reddit\\.com/user/[\\w-]+[/]?$',46    subdomains: ['np', 'ssl', 'blog', 'fr', 'pay', 'es', 'en-us', 'en', 'ru',47      'us', 'de', 'dd', 'no', 'pt', 'ww', 'ss', '4x', 'sv', 'nl', 'hw', 'hr',48      'www'],49    host: 'reddit.com'50  },51  {52    service: "twitter",53    getUsername: function(loc) { return loc.pathname.split('/')[1]; },54    pathMatches: new RegExp('^/([\\w]+)[/]?$'),55    originAndPathMatches: '^https://twitter\\.com/[\\w]+[/]?$',56    subdomains: [],57    host: 'twitter.com',58    css: ['body.ProfilePage']59  },60  {61    service: "github",62    getUsername: function(loc) { return loc.pathname.split('/')[1]; },63    pathMatches: new RegExp('^/([\\w\-]+)[/]?$'),64    originAndPathMatches: '^https://github\\.com/[\\w\-]+[/]?$',65    subdomains: [],66    host: 'github.com',67    css: ['body.page-profile']68  },69  {70    service: "facebook",71    getUsername: function(loc) { return loc.pathname.split('/')[1]; },72    pathMatches: new RegExp('^/([\\w\\.]+)[/]?$'),73    originAndPathMatches: '^https://(www)?\\.facebook\\.com/[\\w\\.]+[/]?$',74    subdomains: ['www'],75    host: 'facebook.com',76    css: ['body.timelineLayout']77  },78  {79    service: "hackernews",80    getUsername: function(loc) { return document.querySelector('.hnuser').text; },81    pathMatches: new RegExp('^/user'),82    originAndPathMatches: '^https://news\\.ycombinator\\.com/user',83    subdomains: [],84    host: 'news.ycombinator.com',85    css: ['html[op="user"]']86  }87];88function getServiceHosts(service) {89  hosts = [service.host]90  for (const subdomain of service.subdomains) {91    hosts.push(subdomain + '.' + service.host)92  }93  return hosts94}95// Match a window.location and document against a service profile and return96// a User instance. Will skip matching CSS if no document is provided.97function matchService(loc, doc, forceService) {98  for (const m of identityMatchers) {99    if (forceService !== undefined && forceService !== m.service) continue;100    const matched = getServiceHosts(m).some(function(hostName) {101      return hostName === loc.hostname102    }) && loc.pathname.match(m.pathMatches);103    if (!matched) continue;104    const username = safeHTML(m.getUsername(loc));105    if (!username) continue;106    if (doc === undefined || m.css === undefined) return new User(username, m.service);107    for (const css of m.css) {108      if (doc.querySelector(css) !== null) {109        return new User(username, m.service);110      }111    }112  }113}114// User keeps track of the original query and which services we resolved for115// this user. It also handles formatting strings for each service.116function User(username, service) {117  if (service === undefined) service = "keybase";118  this.origin = service;119  this.services = {};120  this.services[service] = username;121  this.extraReplyCls = "";122}123// Return a fresh copy equivalent to how it was initialized.124User.prototype.clone = function() {125  user = new User(this.services[this.origin], this.origin);126  user.extraReplyCls = this.extraReplyCls127  return user128}129User.prototype.query = function() {130  const name = this.services[this.origin];131  if (this.origin === "keybase") {132    return name;133  }134  return `${name}@${this.origin}`;135}136User.prototype.display = function(service) {137  if (service === undefined) service = this.origin;138  const name = this.services[this.origin];139  switch (this.origin) {140    case "reddit":141      return `/u/${name}`;142    case "twitter":143      return `@${name}`;144    default:145      return name;146  }147}148User.prototype.href = function(service) {149  if (service === undefined) service = this.origin;150  const name = this.services[this.origin];151  switch (service) {152    case "keybase":153      return `https://keybase.io/${name}`;154    case "reddit":155      return `https://www.reddit.com/user/${name}`;156    case "twitter":157      return `https://twitter.com/${name}`;158    case "facebook":159      return `https://facebook.com/${name}`;160    case "github":161      return `https://github.com/${name}`;162    case "hackernews":163      return `https://news.ycombinator.com/user?id=${name}`;164    default:165      throw `unknown service: ${this.origin}`;166  }167}168// Convert a user input into a string that is safe for inlining into HTML.169function safeHTML(s) {170  if (!s) return "";171  return s.replace(/[&'"<>\/]/g, function (c) {172    // Per https://www.owasp.org/index.php/XSS_(Cross_Site_Scripting)_Prevention_Cheat_Sheet#RULE_.231_-_HTML_Escape_Before_Inserting_Untrusted_Data_into_HTML_Element_Content173    return {174      '&': "&",175      '"': """,176      "'": "'",177      '/': "/",178      '<': "<",179      '>': ">"180    }[c];181  });...fuzzy_file_finder.js
Source:fuzzy_file_finder.js  
1(function() {2  var fs, path;3  path = require('path');4  fs = require('fs');5  module.exports = function(directory, pattern, matchCallback, finalCallback) {6    var buildResult, filePart, fileRegex, listFiles, makePattern, matchFile, matchPath, parts, pathMatches, pathRegex, waitingFiles, withoutBasedir;7    pathMatches = {};8    waitingFiles = 0;9    listFiles = function(root, segments, callback) {10      waitingFiles += 1;11      return fs.readdir(root, function(error, files) {12        waitingFiles -= 1;13        return files.forEach(function(filename) {14          if (filename[0] === '.') {15            return null;16          }17          waitingFiles += 1;18          filename = path.join(root, filename);19          return fs.stat(filename, function(error, stats) {20            waitingFiles -= 1;21            return stats.isDirectory() ? listFiles(filename, segments + 1, callback) : callback(filename, segments);22          });23        });24      });25    };26    withoutBasedir = function(path) {27      return path.replace(directory + '/', '');28    };29    buildResult = function(match, segments) {30      var _a, _b, capture, charRatio, index, inside, insideChars, insideRuns, lastRun, runRatio, runs, totalChars;31      runs = [];32      insideRuns = [];33      lastRun = false;34      insideChars = 0;35      totalChars = 0;36      index = 0;37      match.shift;38      _a = match;39      for (index = 0, _b = _a.length; index < _b; index++) {40        capture = _a[index];41        if (capture.length) {42          inside = index % 2 !== 0;43          capture = capture.replace('/', '');44          totalChars += capture.length;45          if (inside) {46            insideChars += capture.length;47          }48          if (lastRun && lastRun.inside === inside) {49            lastRun.string += capture;50          } else {51            lastRun = {52              string: capture,53              inside: inside54            };55            runs.push(lastRun);56            if (inside) {57              insideRuns.push(lastRun);58            }59          }60        }61      }62      charRatio = totalChars > 0 ? insideChars / totalChars : 1;63      runRatio = insideRuns.length > 0 ? segments / insideRuns.length : 1;64      return {65        score: runRatio * charRatio,66        result: runs,67        missed: false68      };69    };70    matchPath = function(filename, segments) {71      var _a, dirname, match;72      dirname = path.dirname(filename);73      if (typeof (_a = pathMatches[dirname]) !== "undefined" && _a !== null) {74        return pathMatches[dirname];75      }76      if (typeof pathRegex !== "undefined" && pathRegex !== null) {77        match = pathRegex.exec(withoutBasedir(filename));78        return match ? (pathMatches[dirname] = buildResult(match, segments)) : (pathMatches[dirname] = {79          score: 1,80          result: withoutBasedir(dirname),81          missed: true82        });83      } else {84        return (pathMatches[dirname] = {85          score: 1,86          result: withoutBasedir(dirname),87          missed: false88        });89      }90    };91    matchFile = function(filename, pathMatch) {92      var basename, dirname, match, matchResult;93      basename = path.basename(filename);94      dirname = path.dirname(filename);95      match = fileRegex.exec(basename);96      if (match) {97        matchResult = buildResult(match, 1);98        return {99          path: withoutBasedir(filename),100          dirname: withoutBasedir(dirname),101          name: basename,102          pathRuns: pathMatch.result,103          fileRuns: matchResult.result,104          score: pathMatch.score * matchResult.score105        };106      } else {107        return false;108      }109    };110    makePattern = function(part) {111      var charToPattern;112      charToPattern = function(pattern, character) {113        if (pattern.length) {114          pattern += '([^/]*?)';115        }116        return pattern += '(' + character + ')';117      };118      return part.split('').reduce(charToPattern, '');119    };120    pattern = pattern.replace(/ /g, '');121    parts = pattern.split('/');122    if (pattern.match(/\/$/)) {123      parts.push('');124    }125    filePart = parts.pop();126    if (parts.length) {127      pathRegex = new RegExp('^(.*?)' + parts.map(makePattern).join('(.*?/.*?)') + '(.*?)$', 'i');128    }129    fileRegex = (new RegExp("^(.*?)" + (makePattern(filePart)) + "(.*)$", "i"));130    return listFiles(directory, 1, function(filename, segments) {131      var fileMatch, pathMatch;132      pathMatch = matchPath(filename, segments);133      if (!pathMatch.missed) {134        console.log('trying to match ' + filename);135        fileMatch = matchFile(filename, pathMatch);136        if (fileMatch) {137          matchCallback(fileMatch);138        }139        if (waitingFiles === 0 && (typeof finalCallback !== "undefined" && finalCallback !== null)) {140          return finalCallback();141        }142      }143    });144  };...index.js
Source:index.js  
1let path = null2let pathMatches = null3let query = null4let route = null5export default function routeData (state) {6  if (route !== state.route) {7    route = state.route8    path = query = null9  }10  return {11    get path () {12      if (path && state.route === route) return path13      if (!pathMatches) this._buildMatches()14      const found = Object.keys(pathMatches).find(match => {15        return new RegExp(match, 'g').test(state.route)16      })17      const matched = pathMatches[found]18      if (!matched) return {}19      const values = state.route.match(matched.regex).slice(1)20      path = matched.vars.reduce((v, p, i) => {21        return Object.defineProperty(v, p, {22          get () { return values[i] },23          set: this._pathSetter(matched, p)24        })25      }, {})26      return path27    },28    get query () {29      if (query && state.route === route) return query30      const search = document.location.search31      if (!search) return {}32      const pairs = search.slice(1).split('&')33      query = pairs.reduce((q, p) => {34        const [key, value] = p.split('=')35        return Object.defineProperty(q, key, {36          get () { return value },37          set: this._querySetter(key, value)38        })39      }, {})40      return query41    },42    _buildMatches: function () {43      const FIND_ROUTE_VAR = new RegExp('(:\\w+)', 'g')44      const REPL_ROUTE_VAR = '(\\w+)'45      if (state.routes) {46        pathMatches = state.routes.reduce((matches, path) => {47          const vars = (path.match(FIND_ROUTE_VAR) || []).map(v => v.slice(1))48          const regex = path.replace(FIND_ROUTE_VAR, REPL_ROUTE_VAR)49          matches[regex] = { path, regex, vars }50          return matches51        }, {})52      } else {53        pathMatches = {}54      }55    },56    _pathSetter: function (match, prop) {57      return value => {58        const path = match.path.replace(new RegExp(`:${prop}`, 'g'), value)59        state.route = path + document.location.search + document.location.hash60      }61    },62    _querySetter: function (prop, prevValue) {63      return value => {64        const search = document.location.search65          .replace(new RegExp(`${prop}=${prevValue}`, 'g'), `${prop}=${value}`)66        state.route =67          document.location.pathname + search + document.location.hash68      }69    }70  }...client.router.js
Source:client.router.js  
1// -- Package Imports --2const express = require('express');3const { readdirSync } = require('@jsdevtools/readdir-enhanced');4const { join } = require('path');5// -- Set up Vars --6const router = express.Router();7const pathToDist = join(__dirname, 'frontend', 'dist');8// -- Init file list --9try {10  fileArray = readdirSync(pathToDist, {deep: true, sep: "/"});11  console.log(fileArray)12  if (Array.isArray(fileArray) === false || fileArray.length < 1) {13    throw new Error('COULDN\'T FIND ANY FILES IN DIST (Did you compile the frontend for production yet?');14  }15} catch (err) {16  throw err;17}18// -- File Server --19console.log(fileArray);20router.get('/*', (req, res) => {21  const pathMatches = req.originalUrl.match(/((?<=\/)([^?#]{0,})|(\/))/g);22  console.log('Current req path is:', pathMatches)23  if (pathMatches[0] === '/' && pathMatches[1] === '') {24    const completePath = join(pathToDist, 'index.html');25    res.status(200).sendFile(completePath);26  } else if (fileArray.includes(pathMatches[1])) {27    const completePath = join(pathToDist, pathMatches[1]);28    res.status(200).sendFile(completePath); 29  } else {30    const completePath = join(pathToDist, 'index.html');31    res.status(404).sendFile(completePath)32  }33})34// -- Exports --...navactive.js
Source:navactive.js  
...15    active.classList.remove("active");16}17function highlightNew() {18    path = location.pathname.substring(1);19    newActiveItemId = pathMatches(/index|^[ \t\n]*$/) ? "nav-home" :20    pathMatches(/login|register/ ) ? "nav-login" :21    pathMatches(/profile|editaddress|changepassword|editinfo/) ? "nav-profile" :22    pathMatches(/admin/) ? "nav-admin" :23    pathMatches(/listAvailableCar|listReservationCurrentUser|searchCar|reservation|delete/) ? "nav-rsv" :24    pathMatches(/pricing/) ? "nav-pricing" :25    pathMatches(/contact/) ? "nav-contact" :26    pathMatches(/api/) ? "nav-api" : "";27    var element = document.getElementById(newActiveItemId);28    if (element != null) {29        element.classList.add("active");30        element.classList.remove("text-dark");31    }32}33function pathMatches(regex) {34    if (path.match(regex)) {35        return true;36    }37    return false;...functions.js
Source:functions.js  
...15    active.classList.remove("active");16}17function highlightNew() {18    path = location.pathname.substring(1);19    newActiveItemId = pathMatches(/start/) ? "nav-home" :20    pathMatches(/user-edit|user-change-password|user-delete/ ) ? "nav-account" :21    pathMatches(/cars-input/ ) ? "nav-cars-input" :22    pathMatches(/fuel-input|cost-input/) ? "nav-register-data" :23    pathMatches(/charts/) ? "nav-stats" :24    pathMatches(/contact/) ? "nav-contact" : "";25    var element = document.getElementById(newActiveItemId);26    if (element != null) {27        element.classList.add("active");28    }29}30function pathMatches(regex) {31    if (path.match(regex)) {32        return true;33    }34    return false;...Using AI Code Generation
1const { chromium } = require('playwright');2(async () => {3    const browser = await chromium.launch();4    const context = await browser.newContext();5    const page = await context.newPage();6    await browser.close();7})();8const { chromium } = require('playwright');9(async () => {10    const browser = await chromium.launch();11    const context = await browser.newContext();12    const page = await context.newPage();Using AI Code Generation
1const { chromium } = require('playwright');2(async () => {3  const browser = await chromium.launch();4  const context = await browser.newContext();5  const page = await context.newPage();6  await page.waitForSelector('text=Get started');7  await page.click('text=Get started');8  await page.waitForSelector('text=API');9  await page.click('text=API');10  await page.waitForSelector('text=Page');11  await page.click('text=Page');12  await page.waitForSelector('text=pathMatches');13  await page.click('text=pathMatches');14  await page.waitForSelector('text=Page.pathMatches');15  await page.click('text=Page.pathMatches');16  await page.waitForSelector('text=Parameters');17  await page.click('text=Parameters');18  await page.waitForSelector('text=page.pathMatches');19  await page.click('text=page.pathMatches');20  await page.waitForSelector('text=Usage');21  await page.click('text=Usage');22  await page.waitForSelector('text=page.pathMatches');23  await page.click('text=page.pathMatches');24  await page.waitForSelector('text=const');25  await page.click('text=const');26  await page.waitForSelector('text=page.pathMatches');27  await page.click('text=page.pathMatches');28  await page.waitForSelector('text=const');29  await page.click('text=const');30  await page.waitForSelector('text=page.pathMatches');31  await page.click('text=page.pathMatches');32  await page.waitForSelector('text=const');33  await page.click('text=const');34  await page.waitForSelector('text=page.pathMatches');35  await page.click('text=page.pathMatches');36  await page.waitForSelector('text=const');37  await page.click('text=const');38  await page.waitForSelector('text=page.pathMatches');39  await page.click('text=page.pathMatches');40  await page.waitForSelector('text=const');41  await page.click('text=const');42  await page.waitForSelector('text=page.pathMatches');43  await page.click('text=page.pathMatches');44  await page.waitForSelector('text=const');45  await page.click('text=const');46  await page.waitForSelector('text=page.pathMatches');47  await page.click('text=page.pathMatches');48  await page.waitForSelector('text=Using AI Code Generation
1const { pathMatches } = require('playwright/lib/utils/utils');2console.log(pathMatches('/foo', '/foo'));3console.log(pathMatches('/foo', '/foo/bar'));4console.log(pathMatches('/foo/*', '/foo/bar'));5console.log(pathMatches('/foo/*/bar', '/foo/baz/bar'));6console.log(pathMatches('/foo/*/bar', '/foo/baz/baz'));7console.log(pathMatches('/foo/*/bar', '/foo/baz/baz/bar'));8console.log(pathMatches('/foo/*/bar', '/foo/baz/baz/bar/baz'));9console.log(pathMatches('/foo/*/bar', '/foo/baz/baz/bar/baz/baz'));10console.log(pathMatches('/foo/*/bar', '/foo/baz/baz/bar/baz/baz/baz'));11console.log(pathMatches('/foo/*/*', '/foo/baz/baz'));12console.log(pathMatches('/foo/*/*', '/foo/baz/baz/bar'));13console.log(pathMatches('/foo/*/*', '/foo/baz/baz/bar/baz'));14console.log(pathMatches('/foo/*/*', '/foo/baz/baz/bar/baz/baz'));15const { chromium } = require('playwright');16(async () => {17  const browser = await chromium.launch();18  const context = await browser.newContext();19  const page = await context.newPage();20  await page.route('**/foo', route => route.fulfill({21  }));22  await page.goto('Using AI Code Generation
1const { pathMatches } = require('playwright-core/lib/server/network');2console.log(pathMatches('/test', '/test'));3console.log(pathMatches('/test', '/test/'));4console.log(pathMatches('/test', '/test/*'));5console.log(pathMatches('/test', '/test/*/*'));6console.log(pathMatches('/test', '/test/'));7console.log(pathMatches('/test', '/test/*'));8console.log(pathMatches('/test', '/test/*/*'));9console.log(pathMatches('/test', '/test/*/*/*'));10console.log(pathMatches('/test', '/test/*/*/*/*'));11console.log(pathMatches('/test', '/test/*/*/*/*/*'));12console.log(pathMatches('/test', '/test/*/*/*/*/*/*'));13console.log(pathMatches('/test', '/test/*/*/*/*/*/*/*'));14console.log(pathMatches('/test', '/test/*/*/*/*/*/*/*/*'));15console.log(pathMatches('/test', '/test/*/*/*/*/*/*/*/*/*'));16console.log(pathMatchUsing AI Code Generation
1const { test, expect } = require("@playwright/test");2const { pathMatches } = require("@playwright/test/lib/server/routes");3test("should match path", async ({ page }) => {4  expect(pathMatches("/foo", "/foo")).toBe(true);5  expect(pathMatches("/foo", "/foo/bar")).toBe(false);6  expect(pathMatches("/foo", "/foo?bar")).toBe(true);7  expect(pathMatches("/foo?bar", "/foo")).toBe(true);8  expect(pathMatches("/foo?bar", "/foo?bar")).toBe(true);9  expect(pathMatches("/foo?bar", "/foo?bar=1")).toBe(true);10  expect(pathMatches("/foo?bar", "/foo?bar=1&baz=2")).toBe(true);11  expect(pathMatches("/foo?bar=1&baz=2", "/foo?bar=1&baz=2")).toBe(true);12  expect(pathMatches("/foo?bar=1&baz=2", "/foo?baz=2&bar=1")).toBe(true);13  expect(pathMatches("/foo?bar=1&baz=2", "/foo?baz=2")).toBe(true);14  expect(pathMatches("/foo?bar=1&baz=2", "/foo?bar=1")).toBe(true);15  expect(pathMatches("/foo?bar=1&baz=2", "/foo")).toBe(true);16  expect(pathMatches("/foo?bar=1&baz=2", "/foo?bar=1&baz=2&qux=3")).toBe(false);17  expect(pathMatches("/foo?bar=1&baz=2", "/foo?bar=1&baz=2&qux=3")).toBe(false);18  expect(pathMatches("/foo?bar=1&baz=2", "/foo?bar=1&baz=2&qux=3")).toBe(false);19  expect(pathMatches("/foo?bar=1&baz=2", "/foo?bar=1&baz=2&qux=3")).toBe(false);20  expect(pathMatches("/foo?bar=1&baz=2", "/foo?bar=1&baz=2&qux=3")).toBe(false);21  expect(pathMatches("/foo?bar=1&baz=2", "/foo?bar=1&baz=2&qux=3")).toBe(false);22  expect(pathMatches("/foo?barUsing AI Code Generation
1const { pathMatches } = require("playwright/lib/utils/utils");2const path = require("path");3const filePath = path.resolve("test.js");4console.log(pathMatches(filePath, "test.js"));5console.log(pathMatches(filePath, "test.*"));6console.log(pathMatches(filePath, "test.*.js"));Using AI Code Generation
1const { pathMatches } = require('playwright/lib/server/network');2const result = pathMatches(url, pattern);3console.log(result);4const { pathToRegex } = require('playwright/lib/server/network');5const regex = pathToRegex(pattern);6const result = regex.test(url);7console.log(result);Using AI Code Generation
1const { pathMatches } = require('@playwright/test');2console.log(pathMatches('/path/to/file.js', '/path/to/**'));3console.log(pathMatches('/path/to/file.js', '/path/to/*.js'));4console.log(pathMatches('/path/to/file.js', '/path/to/*.txt'));5console.log(pathMatches('/path/to/file.js', '/path/to/*.js', true));6console.log(pathMatches('/path/to/file.js', '/path/to/*.js', true, true));7console.log(pathMatches('/path/to/file.js', '/path/to/*.js', true, false));8console.log(pathMatches('/path/to/file.js', '/path/to/*.js', false, true));9console.log(pathMatches('/path/to/file.js', '/path/to/*.js', false, false));10console.log(pathMatches('/path/to/file.js', '/path/to/*.js', false, false, true));11console.log(pathMatches('/path/to/file.js', '/path/to/*.js', false, false, false));12console.log(pathMatches('/path/to/file.js', '/path/to/*.js', false, false, true, true));13console.log(pathMatches('/path/to/file.js', '/path/to/*.js', false, false, true, false));14console.log(pathMatches('/path/to/file.js', '/path/to/*.js', false, false, false, true));15console.log(pathMatches('/path/to/file.js', '/path/to/*.js', false, false, false, false));16console.log(pathMatches('/path/to/file.js', '/path/to/*.js', false, false, true, true, true));17console.log(pathMatches('/path/to/file.js', '/path/to/*.js', false, false, true, true, false));18console.log(pathMatches('/path/to/file.js', '/path/to/*.js', false, false, true, false, true));19console.log(pathMatches('/path/to/file.js', '/path/to/*.js', false, false, true, false, false));20console.log(pathMatches('/pathUsing AI Code Generation
1const { InternalAPI } = require('playwright/lib/server/instrumentation');2const path = require('path');3const filePath = path.join(__dirname, 'test.js');4const result = InternalAPI.pathMatches(url, filePath);5const { InternalAPI } = require('playwright/lib/server/instrumentation');6const result = InternalAPI.pathMatches(url);7Why do we need to use pathMatches()?8What are the parameters of pathMatches()?9The pathMatches() method accepts two parameters:10What is the return type of pathMatches()?11How to use pathMatches()?LambdaTest’s Playwright tutorial will give you a broader idea about the Playwright automation framework, its unique features, and use cases with examples to exceed your understanding of Playwright testing. This tutorial will give A to Z guidance, from installing the Playwright framework to some best practices and advanced concepts.
Get 100 minutes of automation test minutes FREE!!
