Best JavaScript code snippet using playwright-internal
SourceMap.js
Source:SourceMap.js
1/**2 * Copyright (c) 2015-present, Facebook, Inc.3 * All rights reserved.4 *5 * This source code is licensed under the BSD-style license found in the6 * LICENSE file in the root directory of this source tree. An additional grant7 * of patent rights can be found in the PATENTS file in the same directory.8 *9 * @providesModule SourceMap10 * @generated11 * @extern12 *13 * This module was generated from `node_modules/source-map` by running14 *15 * $ npm install dryice16 * $ node Makefile.dryice.js17 * $ cat dist/source-map.js18 *19 * and wrapping resulting file into `wrapper` function.20 *21 */22/*eslint-disable */23var scope = {};24wrapper.call(scope);25module.exports = scope.sourceMap;26function wrapper() {27/* -*- Mode: js; js-indent-level: 2; -*- */28/*29 * Copyright 2011 Mozilla Foundation and contributors30 * Licensed under the New BSD license. See LICENSE or:31 * http://opensource.org/licenses/BSD-3-Clause32 */33/**34 * Define a module along with a payload.35 * @param {string} moduleName Name for the payload36 * @param {ignored} deps Ignored. For compatibility with CommonJS AMD Spec37 * @param {function} payload Function with (require, exports, module) params38 */39function define(moduleName, deps, payload) {40 if (typeof moduleName != "string") {41 throw new TypeError('Expected string, got: ' + moduleName);42 }43 if (arguments.length == 2) {44 payload = deps;45 }46 if (moduleName in define.modules) {47 throw new Error("Module already defined: " + moduleName);48 }49 define.modules[moduleName] = payload;50};51/**52 * The global store of un-instantiated modules53 */54define.modules = {};55/**56 * We invoke require() in the context of a Domain so we can have multiple57 * sets of modules running separate from each other.58 * This contrasts with JSMs which are singletons, Domains allows us to59 * optionally load a CommonJS module twice with separate data each time.60 * Perhaps you want 2 command lines with a different set of commands in each,61 * for example.62 */63function Domain() {64 this.modules = {};65 this._currentModule = null;66}67(function () {68 /**69 * Lookup module names and resolve them by calling the definition function if70 * needed.71 * There are 2 ways to call this, either with an array of dependencies and a72 * callback to call when the dependencies are found (which can happen73 * asynchronously in an in-page context) or with a single string an no callback74 * where the dependency is resolved synchronously and returned.75 * The API is designed to be compatible with the CommonJS AMD spec and76 * RequireJS.77 * @param {string[]|string} deps A name, or names for the payload78 * @param {function|undefined} callback Function to call when the dependencies79 * are resolved80 * @return {undefined|object} The module required or undefined for81 * array/callback method82 */83 Domain.prototype.require = function(deps, callback) {84 if (Array.isArray(deps)) {85 var params = deps.map(function(dep) {86 return this.lookup(dep);87 }, this);88 if (callback) {89 callback.apply(null, params);90 }91 return undefined;92 }93 else {94 return this.lookup(deps);95 }96 };97 function normalize(path) {98 var bits = path.split('/');99 var i = 1;100 while (i < bits.length) {101 if (bits[i] === '..') {102 bits.splice(i-1, 1);103 } else if (bits[i] === '.') {104 bits.splice(i, 1);105 } else {106 i++;107 }108 }109 return bits.join('/');110 }111 function join(a, b) {112 a = a.trim();113 b = b.trim();114 if (/^\//.test(b)) {115 return b;116 } else {117 return a.replace(/\/*$/, '/') + b;118 }119 }120 function dirname(path) {121 var bits = path.split('/');122 bits.pop();123 return bits.join('/');124 }125 /**126 * Lookup module names and resolve them by calling the definition function if127 * needed.128 * @param {string} moduleName A name for the payload to lookup129 * @return {object} The module specified by aModuleName or null if not found.130 */131 Domain.prototype.lookup = function(moduleName) {132 if (/^\./.test(moduleName)) {133 moduleName = normalize(join(dirname(this._currentModule), moduleName));134 }135 if (moduleName in this.modules) {136 var module = this.modules[moduleName];137 return module;138 }139 if (!(moduleName in define.modules)) {140 throw new Error("Module not defined: " + moduleName);141 }142 var module = define.modules[moduleName];143 if (typeof module == "function") {144 var exports = {};145 var previousModule = this._currentModule;146 this._currentModule = moduleName;147 module(this.require.bind(this), exports, { id: moduleName, uri: "" });148 this._currentModule = previousModule;149 module = exports;150 }151 // cache the resulting module object for next time152 this.modules[moduleName] = module;153 return module;154 };155}());156define.Domain = Domain;157define.globalDomain = new Domain();158var require = define.globalDomain.require.bind(define.globalDomain);159/* -*- Mode: js; js-indent-level: 2; -*- */160/*161 * Copyright 2011 Mozilla Foundation and contributors162 * Licensed under the New BSD license. See LICENSE or:163 * http://opensource.org/licenses/BSD-3-Clause164 */165define('source-map/source-map-generator', ['require', 'exports', 'module' , 'source-map/base64-vlq', 'source-map/util', 'source-map/array-set'], function(require, exports, module) {166 var base64VLQ = require('./base64-vlq');167 var util = require('./util');168 var ArraySet = require('./array-set').ArraySet;169 /**170 * An instance of the SourceMapGenerator represents a source map which is171 * being built incrementally. To create a new one, you must pass an object172 * with the following properties:173 *174 * - file: The filename of the generated source.175 * - sourceRoot: An optional root for all URLs in this source map.176 */177 function SourceMapGenerator(aArgs) {178 this._file = util.getArg(aArgs, 'file');179 this._sourceRoot = util.getArg(aArgs, 'sourceRoot', null);180 this._sources = new ArraySet();181 this._names = new ArraySet();182 this._mappings = [];183 this._sourcesContents = null;184 }185 SourceMapGenerator.prototype._version = 3;186 /**187 * Creates a new SourceMapGenerator based on a SourceMapConsumer188 *189 * @param aSourceMapConsumer The SourceMap.190 */191 SourceMapGenerator.fromSourceMap =192 function SourceMapGenerator_fromSourceMap(aSourceMapConsumer) {193 var sourceRoot = aSourceMapConsumer.sourceRoot;194 var generator = new SourceMapGenerator({195 file: aSourceMapConsumer.file,196 sourceRoot: sourceRoot197 });198 aSourceMapConsumer.eachMapping(function (mapping) {199 var newMapping = {200 generated: {201 line: mapping.generatedLine,202 column: mapping.generatedColumn203 }204 };205 if (mapping.source) {206 newMapping.source = mapping.source;207 if (sourceRoot) {208 newMapping.source = util.relative(sourceRoot, newMapping.source);209 }210 newMapping.original = {211 line: mapping.originalLine,212 column: mapping.originalColumn213 };214 if (mapping.name) {215 newMapping.name = mapping.name;216 }217 }218 generator.addMapping(newMapping);219 });220 aSourceMapConsumer.sources.forEach(function (sourceFile) {221 var content = aSourceMapConsumer.sourceContentFor(sourceFile);222 if (content) {223 generator.setSourceContent(sourceFile, content);224 }225 });226 return generator;227 };228 /**229 * Add a single mapping from original source line and column to the generated230 * source's line and column for this source map being created. The mapping231 * object should have the following properties:232 *233 * - generated: An object with the generated line and column positions.234 * - original: An object with the original line and column positions.235 * - source: The original source file (relative to the sourceRoot).236 * - name: An optional original token name for this mapping.237 */238 SourceMapGenerator.prototype.addMapping =239 function SourceMapGenerator_addMapping(aArgs) {240 var generated = util.getArg(aArgs, 'generated');241 var original = util.getArg(aArgs, 'original', null);242 var source = util.getArg(aArgs, 'source', null);243 var name = util.getArg(aArgs, 'name', null);244 this._validateMapping(generated, original, source, name);245 if (source && !this._sources.has(source)) {246 this._sources.add(source);247 }248 if (name && !this._names.has(name)) {249 this._names.add(name);250 }251 this._mappings.push({252 generatedLine: generated.line,253 generatedColumn: generated.column,254 originalLine: original != null && original.line,255 originalColumn: original != null && original.column,256 source: source,257 name: name258 });259 };260 /**261 * Set the source content for a source file.262 */263 SourceMapGenerator.prototype.setSourceContent =264 function SourceMapGenerator_setSourceContent(aSourceFile, aSourceContent) {265 var source = aSourceFile;266 if (this._sourceRoot) {267 source = util.relative(this._sourceRoot, source);268 }269 if (aSourceContent !== null) {270 // Add the source content to the _sourcesContents map.271 // Create a new _sourcesContents map if the property is null.272 if (!this._sourcesContents) {273 this._sourcesContents = {};274 }275 this._sourcesContents[util.toSetString(source)] = aSourceContent;276 } else {277 // Remove the source file from the _sourcesContents map.278 // If the _sourcesContents map is empty, set the property to null.279 delete this._sourcesContents[util.toSetString(source)];280 if (Object.keys(this._sourcesContents).length === 0) {281 this._sourcesContents = null;282 }283 }284 };285 /**286 * Applies the mappings of a sub-source-map for a specific source file to the287 * source map being generated. Each mapping to the supplied source file is288 * rewritten using the supplied source map. Note: The resolution for the289 * resulting mappings is the minimium of this map and the supplied map.290 *291 * @param aSourceMapConsumer The source map to be applied.292 * @param aSourceFile Optional. The filename of the source file.293 * If omitted, SourceMapConsumer's file property will be used.294 */295 SourceMapGenerator.prototype.applySourceMap =296 function SourceMapGenerator_applySourceMap(aSourceMapConsumer, aSourceFile) {297 // If aSourceFile is omitted, we will use the file property of the SourceMap298 if (!aSourceFile) {299 aSourceFile = aSourceMapConsumer.file;300 }301 var sourceRoot = this._sourceRoot;302 // Make "aSourceFile" relative if an absolute Url is passed.303 if (sourceRoot) {304 aSourceFile = util.relative(sourceRoot, aSourceFile);305 }306 // Applying the SourceMap can add and remove items from the sources and307 // the names array.308 var newSources = new ArraySet();309 var newNames = new ArraySet();310 // Find mappings for the "aSourceFile"311 this._mappings.forEach(function (mapping) {312 if (mapping.source === aSourceFile && mapping.originalLine) {313 // Check if it can be mapped by the source map, then update the mapping.314 var original = aSourceMapConsumer.originalPositionFor({315 line: mapping.originalLine,316 column: mapping.originalColumn317 });318 if (original.source !== null) {319 // Copy mapping320 if (sourceRoot) {321 mapping.source = util.relative(sourceRoot, original.source);322 } else {323 mapping.source = original.source;324 }325 mapping.originalLine = original.line;326 mapping.originalColumn = original.column;327 if (original.name !== null && mapping.name !== null) {328 // Only use the identifier name if it's an identifier329 // in both SourceMaps330 mapping.name = original.name;331 }332 }333 }334 var source = mapping.source;335 if (source && !newSources.has(source)) {336 newSources.add(source);337 }338 var name = mapping.name;339 if (name && !newNames.has(name)) {340 newNames.add(name);341 }342 }, this);343 this._sources = newSources;344 this._names = newNames;345 // Copy sourcesContents of applied map.346 aSourceMapConsumer.sources.forEach(function (sourceFile) {347 var content = aSourceMapConsumer.sourceContentFor(sourceFile);348 if (content) {349 if (sourceRoot) {350 sourceFile = util.relative(sourceRoot, sourceFile);351 }352 this.setSourceContent(sourceFile, content);353 }354 }, this);355 };356 /**357 * A mapping can have one of the three levels of data:358 *359 * 1. Just the generated position.360 * 2. The Generated position, original position, and original source.361 * 3. Generated and original position, original source, as well as a name362 * token.363 *364 * To maintain consistency, we validate that any new mapping being added falls365 * in to one of these categories.366 */367 SourceMapGenerator.prototype._validateMapping =368 function SourceMapGenerator_validateMapping(aGenerated, aOriginal, aSource,369 aName) {370 if (aGenerated && 'line' in aGenerated && 'column' in aGenerated371 && aGenerated.line > 0 && aGenerated.column >= 0372 && !aOriginal && !aSource && !aName) {373 // Case 1.374 return;375 }376 else if (aGenerated && 'line' in aGenerated && 'column' in aGenerated377 && aOriginal && 'line' in aOriginal && 'column' in aOriginal378 && aGenerated.line > 0 && aGenerated.column >= 0379 && aOriginal.line > 0 && aOriginal.column >= 0380 && aSource) {381 // Cases 2 and 3.382 return;383 }384 else {385 throw new Error('Invalid mapping: ' + JSON.stringify({386 generated: aGenerated,387 source: aSource,388 orginal: aOriginal,389 name: aName390 }));391 }392 };393 /**394 * Serialize the accumulated mappings in to the stream of base 64 VLQs395 * specified by the source map format.396 */397 SourceMapGenerator.prototype._serializeMappings =398 function SourceMapGenerator_serializeMappings() {399 var previousGeneratedColumn = 0;400 var previousGeneratedLine = 1;401 var previousOriginalColumn = 0;402 var previousOriginalLine = 0;403 var previousName = 0;404 var previousSource = 0;405 var result = '';406 var mapping;407 // The mappings must be guaranteed to be in sorted order before we start408 // serializing them or else the generated line numbers (which are defined409 // via the ';' separators) will be all messed up. Note: it might be more410 // performant to maintain the sorting as we insert them, rather than as we411 // serialize them, but the big O is the same either way.412 this._mappings.sort(util.compareByGeneratedPositions);413 for (var i = 0, len = this._mappings.length; i < len; i++) {414 mapping = this._mappings[i];415 if (mapping.generatedLine !== previousGeneratedLine) {416 previousGeneratedColumn = 0;417 while (mapping.generatedLine !== previousGeneratedLine) {418 result += ';';419 previousGeneratedLine++;420 }421 }422 else {423 if (i > 0) {424 if (!util.compareByGeneratedPositions(mapping, this._mappings[i - 1])) {425 continue;426 }427 result += ',';428 }429 }430 result += base64VLQ.encode(mapping.generatedColumn431 - previousGeneratedColumn);432 previousGeneratedColumn = mapping.generatedColumn;433 if (mapping.source) {434 result += base64VLQ.encode(this._sources.indexOf(mapping.source)435 - previousSource);436 previousSource = this._sources.indexOf(mapping.source);437 // lines are stored 0-based in SourceMap spec version 3438 result += base64VLQ.encode(mapping.originalLine - 1439 - previousOriginalLine);440 previousOriginalLine = mapping.originalLine - 1;441 result += base64VLQ.encode(mapping.originalColumn442 - previousOriginalColumn);443 previousOriginalColumn = mapping.originalColumn;444 if (mapping.name) {445 result += base64VLQ.encode(this._names.indexOf(mapping.name)446 - previousName);447 previousName = this._names.indexOf(mapping.name);448 }449 }450 }451 return result;452 };453 SourceMapGenerator.prototype._generateSourcesContent =454 function SourceMapGenerator_generateSourcesContent(aSources, aSourceRoot) {455 return aSources.map(function (source) {456 if (!this._sourcesContents) {457 return null;458 }459 if (aSourceRoot) {460 source = util.relative(aSourceRoot, source);461 }462 var key = util.toSetString(source);463 return Object.prototype.hasOwnProperty.call(this._sourcesContents,464 key)465 ? this._sourcesContents[key]466 : null;467 }, this);468 };469 /**470 * Externalize the source map.471 */472 SourceMapGenerator.prototype.toJSON =473 function SourceMapGenerator_toJSON() {474 var map = {475 version: this._version,476 file: this._file,477 sources: this._sources.toArray(),478 names: this._names.toArray(),479 mappings: this._serializeMappings()480 };481 if (this._sourceRoot) {482 map.sourceRoot = this._sourceRoot;483 }484 if (this._sourcesContents) {485 map.sourcesContent = this._generateSourcesContent(map.sources, map.sourceRoot);486 }487 return map;488 };489 /**490 * Render the source map being generated to a string.491 */492 SourceMapGenerator.prototype.toString =493 function SourceMapGenerator_toString() {494 return JSON.stringify(this);495 };496 exports.SourceMapGenerator = SourceMapGenerator;497});498/* -*- Mode: js; js-indent-level: 2; -*- */499/*500 * Copyright 2011 Mozilla Foundation and contributors501 * Licensed under the New BSD license. See LICENSE or:502 * http://opensource.org/licenses/BSD-3-Clause503 *504 * Based on the Base 64 VLQ implementation in Closure Compiler:505 * https://code.google.com/p/closure-compiler/source/browse/trunk/src/com/google/debugging/sourcemap/Base64VLQ.java506 *507 * Copyright 2011 The Closure Compiler Authors. All rights reserved.508 * Redistribution and use in source and binary forms, with or without509 * modification, are permitted provided that the following conditions are510 * met:511 *512 * * Redistributions of source code must retain the above copyright513 * notice, this list of conditions and the following disclaimer.514 * * Redistributions in binary form must reproduce the above515 * copyright notice, this list of conditions and the following516 * disclaimer in the documentation and/or other materials provided517 * with the distribution.518 * * Neither the name of Google Inc. nor the names of its519 * contributors may be used to endorse or promote products derived520 * from this software without specific prior written permission.521 *522 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS523 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT524 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR525 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT526 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,527 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT528 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,529 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY530 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT531 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE532 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.533 */534define('source-map/base64-vlq', ['require', 'exports', 'module' , 'source-map/base64'], function(require, exports, module) {535 var base64 = require('./base64');536 // A single base 64 digit can contain 6 bits of data. For the base 64 variable537 // length quantities we use in the source map spec, the first bit is the sign,538 // the next four bits are the actual value, and the 6th bit is the539 // continuation bit. The continuation bit tells us whether there are more540 // digits in this value following this digit.541 //542 // Continuation543 // | Sign544 // | |545 // V V546 // 101011547 var VLQ_BASE_SHIFT = 5;548 // binary: 100000549 var VLQ_BASE = 1 << VLQ_BASE_SHIFT;550 // binary: 011111551 var VLQ_BASE_MASK = VLQ_BASE - 1;552 // binary: 100000553 var VLQ_CONTINUATION_BIT = VLQ_BASE;554 /**555 * Converts from a two-complement value to a value where the sign bit is556 * is placed in the least significant bit. For example, as decimals:557 * 1 becomes 2 (10 binary), -1 becomes 3 (11 binary)558 * 2 becomes 4 (100 binary), -2 becomes 5 (101 binary)559 */560 function toVLQSigned(aValue) {561 return aValue < 0562 ? ((-aValue) << 1) + 1563 : (aValue << 1) + 0;564 }565 /**566 * Converts to a two-complement value from a value where the sign bit is567 * is placed in the least significant bit. For example, as decimals:568 * 2 (10 binary) becomes 1, 3 (11 binary) becomes -1569 * 4 (100 binary) becomes 2, 5 (101 binary) becomes -2570 */571 function fromVLQSigned(aValue) {572 var isNegative = (aValue & 1) === 1;573 var shifted = aValue >> 1;574 return isNegative575 ? -shifted576 : shifted;577 }578 /**579 * Returns the base 64 VLQ encoded value.580 */581 exports.encode = function base64VLQ_encode(aValue) {582 var encoded = "";583 var digit;584 var vlq = toVLQSigned(aValue);585 do {586 digit = vlq & VLQ_BASE_MASK;587 vlq >>>= VLQ_BASE_SHIFT;588 if (vlq > 0) {589 // There are still more digits in this value, so we must make sure the590 // continuation bit is marked.591 digit |= VLQ_CONTINUATION_BIT;592 }593 encoded += base64.encode(digit);594 } while (vlq > 0);595 return encoded;596 };597 /**598 * Decodes the next base 64 VLQ value from the given string and returns the599 * value and the rest of the string.600 */601 exports.decode = function base64VLQ_decode(aStr) {602 var i = 0;603 var strLen = aStr.length;604 var result = 0;605 var shift = 0;606 var continuation, digit;607 do {608 if (i >= strLen) {609 throw new Error("Expected more digits in base 64 VLQ value.");610 }611 digit = base64.decode(aStr.charAt(i++));612 continuation = !!(digit & VLQ_CONTINUATION_BIT);613 digit &= VLQ_BASE_MASK;614 result = result + (digit << shift);615 shift += VLQ_BASE_SHIFT;616 } while (continuation);617 return {618 value: fromVLQSigned(result),619 rest: aStr.slice(i)620 };621 };622});623/* -*- Mode: js; js-indent-level: 2; -*- */624/*625 * Copyright 2011 Mozilla Foundation and contributors626 * Licensed under the New BSD license. See LICENSE or:627 * http://opensource.org/licenses/BSD-3-Clause628 */629define('source-map/base64', ['require', 'exports', 'module' , ], function(require, exports, module) {630 var charToIntMap = {};631 var intToCharMap = {};632 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'633 .split('')634 .forEach(function (ch, index) {635 charToIntMap[ch] = index;636 intToCharMap[index] = ch;637 });638 /**639 * Encode an integer in the range of 0 to 63 to a single base 64 digit.640 */641 exports.encode = function base64_encode(aNumber) {642 if (aNumber in intToCharMap) {643 return intToCharMap[aNumber];644 }645 throw new TypeError("Must be between 0 and 63: " + aNumber);646 };647 /**648 * Decode a single base 64 digit to an integer.649 */650 exports.decode = function base64_decode(aChar) {651 if (aChar in charToIntMap) {652 return charToIntMap[aChar];653 }654 throw new TypeError("Not a valid base 64 digit: " + aChar);655 };656});657/* -*- Mode: js; js-indent-level: 2; -*- */658/*659 * Copyright 2011 Mozilla Foundation and contributors660 * Licensed under the New BSD license. See LICENSE or:661 * http://opensource.org/licenses/BSD-3-Clause662 */663define('source-map/util', ['require', 'exports', 'module' , ], function(require, exports, module) {664 /**665 * This is a helper function for getting values from parameter/options666 * objects.667 *668 * @param args The object we are extracting values from669 * @param name The name of the property we are getting.670 * @param defaultValue An optional value to return if the property is missing671 * from the object. If this is not specified and the property is missing, an672 * error will be thrown.673 */674 function getArg(aArgs, aName, aDefaultValue) {675 if (aName in aArgs) {676 return aArgs[aName];677 } else if (arguments.length === 3) {678 return aDefaultValue;679 } else {680 throw new Error('"' + aName + '" is a required argument.');681 }682 }683 exports.getArg = getArg;684 var urlRegexp = /([\w+\-.]+):\/\/((\w+:\w+)@)?([\w.]+)?(:(\d+))?(\S+)?/;685 var dataUrlRegexp = /^data:.+\,.+/;686 function urlParse(aUrl) {687 var match = aUrl.match(urlRegexp);688 if (!match) {689 return null;690 }691 return {692 scheme: match[1],693 auth: match[3],694 host: match[4],695 port: match[6],696 path: match[7]697 };698 }699 exports.urlParse = urlParse;700 function urlGenerate(aParsedUrl) {701 var url = aParsedUrl.scheme + "://";702 if (aParsedUrl.auth) {703 url += aParsedUrl.auth + "@"704 }705 if (aParsedUrl.host) {706 url += aParsedUrl.host;707 }708 if (aParsedUrl.port) {709 url += ":" + aParsedUrl.port710 }711 if (aParsedUrl.path) {712 url += aParsedUrl.path;713 }714 return url;715 }716 exports.urlGenerate = urlGenerate;717 function join(aRoot, aPath) {718 var url;719 if (aPath.match(urlRegexp) || aPath.match(dataUrlRegexp)) {720 return aPath;721 }722 if (aPath.charAt(0) === '/' && (url = urlParse(aRoot))) {723 url.path = aPath;724 return urlGenerate(url);725 }726 return aRoot.replace(/\/$/, '') + '/' + aPath;727 }728 exports.join = join;729 /**730 * Because behavior goes wacky when you set `__proto__` on objects, we731 * have to prefix all the strings in our set with an arbitrary character.732 *733 * See https://github.com/mozilla/source-map/pull/31 and734 * https://github.com/mozilla/source-map/issues/30735 *736 * @param String aStr737 */738 function toSetString(aStr) {739 return '$' + aStr;740 }741 exports.toSetString = toSetString;742 function fromSetString(aStr) {743 return aStr.substr(1);744 }745 exports.fromSetString = fromSetString;746 function relative(aRoot, aPath) {747 aRoot = aRoot.replace(/\/$/, '');748 var url = urlParse(aRoot);749 if (aPath.charAt(0) == "/" && url && url.path == "/") {750 return aPath.slice(1);751 }752 return aPath.indexOf(aRoot + '/') === 0753 ? aPath.substr(aRoot.length + 1)754 : aPath;755 }756 exports.relative = relative;757 function strcmp(aStr1, aStr2) {758 var s1 = aStr1 || "";759 var s2 = aStr2 || "";760 return (s1 > s2) - (s1 < s2);761 }762 /**763 * Comparator between two mappings where the original positions are compared.764 *765 * Optionally pass in `true` as `onlyCompareGenerated` to consider two766 * mappings with the same original source/line/column, but different generated767 * line and column the same. Useful when searching for a mapping with a768 * stubbed out mapping.769 */770 function compareByOriginalPositions(mappingA, mappingB, onlyCompareOriginal) {771 var cmp;772 cmp = strcmp(mappingA.source, mappingB.source);773 if (cmp) {774 return cmp;775 }776 cmp = mappingA.originalLine - mappingB.originalLine;777 if (cmp) {778 return cmp;779 }780 cmp = mappingA.originalColumn - mappingB.originalColumn;781 if (cmp || onlyCompareOriginal) {782 return cmp;783 }784 cmp = strcmp(mappingA.name, mappingB.name);785 if (cmp) {786 return cmp;787 }788 cmp = mappingA.generatedLine - mappingB.generatedLine;789 if (cmp) {790 return cmp;791 }792 return mappingA.generatedColumn - mappingB.generatedColumn;793 };794 exports.compareByOriginalPositions = compareByOriginalPositions;795 /**796 * Comparator between two mappings where the generated positions are797 * compared.798 *799 * Optionally pass in `true` as `onlyCompareGenerated` to consider two800 * mappings with the same generated line and column, but different801 * source/name/original line and column the same. Useful when searching for a802 * mapping with a stubbed out mapping.803 */804 function compareByGeneratedPositions(mappingA, mappingB, onlyCompareGenerated) {805 var cmp;806 cmp = mappingA.generatedLine - mappingB.generatedLine;807 if (cmp) {808 return cmp;809 }810 cmp = mappingA.generatedColumn - mappingB.generatedColumn;811 if (cmp || onlyCompareGenerated) {812 return cmp;813 }814 cmp = strcmp(mappingA.source, mappingB.source);815 if (cmp) {816 return cmp;817 }818 cmp = mappingA.originalLine - mappingB.originalLine;819 if (cmp) {820 return cmp;821 }822 cmp = mappingA.originalColumn - mappingB.originalColumn;823 if (cmp) {824 return cmp;825 }826 return strcmp(mappingA.name, mappingB.name);827 };828 exports.compareByGeneratedPositions = compareByGeneratedPositions;829});830/* -*- Mode: js; js-indent-level: 2; -*- */831/*832 * Copyright 2011 Mozilla Foundation and contributors833 * Licensed under the New BSD license. See LICENSE or:834 * http://opensource.org/licenses/BSD-3-Clause835 */836define('source-map/array-set', ['require', 'exports', 'module' , 'source-map/util'], function(require, exports, module) {837 var util = require('./util');838 /**839 * A data structure which is a combination of an array and a set. Adding a new840 * member is O(1), testing for membership is O(1), and finding the index of an841 * element is O(1). Removing elements from the set is not supported. Only842 * strings are supported for membership.843 */844 function ArraySet() {845 this._array = [];846 this._set = {};847 }848 /**849 * Static method for creating ArraySet instances from an existing array.850 */851 ArraySet.fromArray = function ArraySet_fromArray(aArray, aAllowDuplicates) {852 var set = new ArraySet();853 for (var i = 0, len = aArray.length; i < len; i++) {854 set.add(aArray[i], aAllowDuplicates);855 }856 return set;857 };858 /**859 * Add the given string to this set.860 *861 * @param String aStr862 */863 ArraySet.prototype.add = function ArraySet_add(aStr, aAllowDuplicates) {864 var isDuplicate = this.has(aStr);865 var idx = this._array.length;866 if (!isDuplicate || aAllowDuplicates) {867 this._array.push(aStr);868 }869 if (!isDuplicate) {870 this._set[util.toSetString(aStr)] = idx;871 }872 };873 /**874 * Is the given string a member of this set?875 *876 * @param String aStr877 */878 ArraySet.prototype.has = function ArraySet_has(aStr) {879 return Object.prototype.hasOwnProperty.call(this._set,880 util.toSetString(aStr));881 };882 /**883 * What is the index of the given string in the array?884 *885 * @param String aStr886 */887 ArraySet.prototype.indexOf = function ArraySet_indexOf(aStr) {888 if (this.has(aStr)) {889 return this._set[util.toSetString(aStr)];890 }891 throw new Error('"' + aStr + '" is not in the set.');892 };893 /**894 * What is the element at the given index?895 *896 * @param Number aIdx897 */898 ArraySet.prototype.at = function ArraySet_at(aIdx) {899 if (aIdx >= 0 && aIdx < this._array.length) {900 return this._array[aIdx];901 }902 throw new Error('No element indexed by ' + aIdx);903 };904 /**905 * Returns the array representation of this set (which has the proper indices906 * indicated by indexOf). Note that this is a copy of the internal array used907 * for storing the members so that no one can mess with internal state.908 */909 ArraySet.prototype.toArray = function ArraySet_toArray() {910 return this._array.slice();911 };912 exports.ArraySet = ArraySet;913});914/* -*- Mode: js; js-indent-level: 2; -*- */915/*916 * Copyright 2011 Mozilla Foundation and contributors917 * Licensed under the New BSD license. See LICENSE or:918 * http://opensource.org/licenses/BSD-3-Clause919 */920define('source-map/source-map-consumer', ['require', 'exports', 'module' , 'source-map/util', 'source-map/binary-search', 'source-map/array-set', 'source-map/base64-vlq'], function(require, exports, module) {921 var util = require('./util');922 var binarySearch = require('./binary-search');923 var ArraySet = require('./array-set').ArraySet;924 var base64VLQ = require('./base64-vlq');925 /**926 * A SourceMapConsumer instance represents a parsed source map which we can927 * query for information about the original file positions by giving it a file928 * position in the generated source.929 *930 * The only parameter is the raw source map (either as a JSON string, or931 * already parsed to an object). According to the spec, source maps have the932 * following attributes:933 *934 * - version: Which version of the source map spec this map is following.935 * - sources: An array of URLs to the original source files.936 * - names: An array of identifiers which can be referrenced by individual mappings.937 * - sourceRoot: Optional. The URL root from which all sources are relative.938 * - sourcesContent: Optional. An array of contents of the original source files.939 * - mappings: A string of base64 VLQs which contain the actual mappings.940 * - file: The generated file this source map is associated with.941 *942 * Here is an example source map, taken from the source map spec[0]:943 *944 * {945 * version : 3,946 * file: "out.js",947 * sourceRoot : "",948 * sources: ["foo.js", "bar.js"],949 * names: ["src", "maps", "are", "fun"],950 * mappings: "AA,AB;;ABCDE;"951 * }952 *953 * [0]: https://docs.google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k/edit?pli=1#954 */955 function SourceMapConsumer(aSourceMap) {956 var sourceMap = aSourceMap;957 if (typeof aSourceMap === 'string') {958 sourceMap = JSON.parse(aSourceMap.replace(/^\)\]\}'/, ''));959 }960 var version = util.getArg(sourceMap, 'version');961 var sources = util.getArg(sourceMap, 'sources');962 // Sass 3.3 leaves out the 'names' array, so we deviate from the spec (which963 // requires the array) to play nice here.964 var names = util.getArg(sourceMap, 'names', []);965 var sourceRoot = util.getArg(sourceMap, 'sourceRoot', null);966 var sourcesContent = util.getArg(sourceMap, 'sourcesContent', null);967 var mappings = util.getArg(sourceMap, 'mappings');968 var file = util.getArg(sourceMap, 'file', null);969 // Once again, Sass deviates from the spec and supplies the version as a970 // string rather than a number, so we use loose equality checking here.971 if (version != this._version) {972 throw new Error('Unsupported version: ' + version);973 }974 // Pass `true` below to allow duplicate names and sources. While source maps975 // are intended to be compressed and deduplicated, the TypeScript compiler976 // sometimes generates source maps with duplicates in them. See Github issue977 // #72 and bugzil.la/889492.978 this._names = ArraySet.fromArray(names, true);979 this._sources = ArraySet.fromArray(sources, true);980 this.sourceRoot = sourceRoot;981 this.sourcesContent = sourcesContent;982 this._mappings = mappings;983 this.file = file;984 }985 /**986 * Create a SourceMapConsumer from a SourceMapGenerator.987 *988 * @param SourceMapGenerator aSourceMap989 * The source map that will be consumed.990 * @returns SourceMapConsumer991 */992 SourceMapConsumer.fromSourceMap =993 function SourceMapConsumer_fromSourceMap(aSourceMap) {994 var smc = Object.create(SourceMapConsumer.prototype);995 smc._names = ArraySet.fromArray(aSourceMap._names.toArray(), true);996 smc._sources = ArraySet.fromArray(aSourceMap._sources.toArray(), true);997 smc.sourceRoot = aSourceMap._sourceRoot;998 smc.sourcesContent = aSourceMap._generateSourcesContent(smc._sources.toArray(),999 smc.sourceRoot);1000 smc.file = aSourceMap._file;1001 smc.__generatedMappings = aSourceMap._mappings.slice()1002 .sort(util.compareByGeneratedPositions);1003 smc.__originalMappings = aSourceMap._mappings.slice()1004 .sort(util.compareByOriginalPositions);1005 return smc;1006 };1007 /**1008 * The version of the source mapping spec that we are consuming.1009 */1010 SourceMapConsumer.prototype._version = 3;1011 /**1012 * The list of original sources.1013 */1014 Object.defineProperty(SourceMapConsumer.prototype, 'sources', {1015 get: function () {1016 return this._sources.toArray().map(function (s) {1017 return this.sourceRoot ? util.join(this.sourceRoot, s) : s;1018 }, this);1019 }1020 });1021 // `__generatedMappings` and `__originalMappings` are arrays that hold the1022 // parsed mapping coordinates from the source map's "mappings" attribute. They1023 // are lazily instantiated, accessed via the `_generatedMappings` and1024 // `_originalMappings` getters respectively, and we only parse the mappings1025 // and create these arrays once queried for a source location. We jump through1026 // these hoops because there can be many thousands of mappings, and parsing1027 // them is expensive, so we only want to do it if we must.1028 //1029 // Each object in the arrays is of the form:1030 //1031 // {1032 // generatedLine: The line number in the generated code,1033 // generatedColumn: The column number in the generated code,1034 // source: The path to the original source file that generated this1035 // chunk of code,1036 // originalLine: The line number in the original source that1037 // corresponds to this chunk of generated code,1038 // originalColumn: The column number in the original source that1039 // corresponds to this chunk of generated code,1040 // name: The name of the original symbol which generated this chunk of1041 // code.1042 // }1043 //1044 // All properties except for `generatedLine` and `generatedColumn` can be1045 // `null`.1046 //1047 // `_generatedMappings` is ordered by the generated positions.1048 //1049 // `_originalMappings` is ordered by the original positions.1050 SourceMapConsumer.prototype.__generatedMappings = null;1051 Object.defineProperty(SourceMapConsumer.prototype, '_generatedMappings', {1052 get: function () {1053 if (!this.__generatedMappings) {1054 this.__generatedMappings = [];1055 this.__originalMappings = [];1056 this._parseMappings(this._mappings, this.sourceRoot);1057 }1058 return this.__generatedMappings;1059 }1060 });1061 SourceMapConsumer.prototype.__originalMappings = null;1062 Object.defineProperty(SourceMapConsumer.prototype, '_originalMappings', {1063 get: function () {1064 if (!this.__originalMappings) {1065 this.__generatedMappings = [];1066 this.__originalMappings = [];1067 this._parseMappings(this._mappings, this.sourceRoot);1068 }1069 return this.__originalMappings;1070 }1071 });1072 /**1073 * Parse the mappings in a string in to a data structure which we can easily1074 * query (the ordered arrays in the `this.__generatedMappings` and1075 * `this.__originalMappings` properties).1076 */1077 SourceMapConsumer.prototype._parseMappings =1078 function SourceMapConsumer_parseMappings(aStr, aSourceRoot) {1079 var generatedLine = 1;1080 var previousGeneratedColumn = 0;1081 var previousOriginalLine = 0;1082 var previousOriginalColumn = 0;1083 var previousSource = 0;1084 var previousName = 0;1085 var mappingSeparator = /^[,;]/;1086 var str = aStr;1087 var mapping;1088 var temp;1089 while (str.length > 0) {1090 if (str.charAt(0) === ';') {1091 generatedLine++;1092 str = str.slice(1);1093 previousGeneratedColumn = 0;1094 }1095 else if (str.charAt(0) === ',') {1096 str = str.slice(1);1097 }1098 else {1099 mapping = {};1100 mapping.generatedLine = generatedLine;1101 // Generated column.1102 temp = base64VLQ.decode(str);1103 mapping.generatedColumn = previousGeneratedColumn + temp.value;1104 previousGeneratedColumn = mapping.generatedColumn;1105 str = temp.rest;1106 if (str.length > 0 && !mappingSeparator.test(str.charAt(0))) {1107 // Original source.1108 temp = base64VLQ.decode(str);1109 mapping.source = this._sources.at(previousSource + temp.value);1110 previousSource += temp.value;1111 str = temp.rest;1112 if (str.length === 0 || mappingSeparator.test(str.charAt(0))) {1113 throw new Error('Found a source, but no line and column');1114 }1115 // Original line.1116 temp = base64VLQ.decode(str);1117 mapping.originalLine = previousOriginalLine + temp.value;1118 previousOriginalLine = mapping.originalLine;1119 // Lines are stored 0-based1120 mapping.originalLine += 1;1121 str = temp.rest;1122 if (str.length === 0 || mappingSeparator.test(str.charAt(0))) {1123 throw new Error('Found a source and line, but no column');1124 }1125 // Original column.1126 temp = base64VLQ.decode(str);1127 mapping.originalColumn = previousOriginalColumn + temp.value;1128 previousOriginalColumn = mapping.originalColumn;1129 str = temp.rest;1130 if (str.length > 0 && !mappingSeparator.test(str.charAt(0))) {1131 // Original name.1132 temp = base64VLQ.decode(str);1133 mapping.name = this._names.at(previousName + temp.value);1134 previousName += temp.value;1135 str = temp.rest;1136 }1137 }1138 this.__generatedMappings.push(mapping);1139 if (typeof mapping.originalLine === 'number') {1140 this.__originalMappings.push(mapping);1141 }1142 }1143 }1144 this.__originalMappings.sort(util.compareByOriginalPositions);1145 };1146 /**1147 * Find the mapping that best matches the hypothetical "needle" mapping that1148 * we are searching for in the given "haystack" of mappings.1149 */1150 SourceMapConsumer.prototype._findMapping =1151 function SourceMapConsumer_findMapping(aNeedle, aMappings, aLineName,1152 aColumnName, aComparator) {1153 // To return the position we are searching for, we must first find the1154 // mapping for the given position and then return the opposite position it1155 // points to. Because the mappings are sorted, we can use binary search to1156 // find the best mapping.1157 if (aNeedle[aLineName] <= 0) {1158 throw new TypeError('Line must be greater than or equal to 1, got '1159 + aNeedle[aLineName]);1160 }1161 if (aNeedle[aColumnName] < 0) {1162 throw new TypeError('Column must be greater than or equal to 0, got '1163 + aNeedle[aColumnName]);1164 }1165 return binarySearch.search(aNeedle, aMappings, aComparator);1166 };1167 /**1168 * Returns the original source, line, and column information for the generated1169 * source's line and column positions provided. The only argument is an object1170 * with the following properties:1171 *1172 * - line: The line number in the generated source.1173 * - column: The column number in the generated source.1174 *1175 * and an object is returned with the following properties:1176 *1177 * - source: The original source file, or null.1178 * - line: The line number in the original source, or null.1179 * - column: The column number in the original source, or null.1180 * - name: The original identifier, or null.1181 */1182 SourceMapConsumer.prototype.originalPositionFor =1183 function SourceMapConsumer_originalPositionFor(aArgs) {1184 var needle = {1185 generatedLine: util.getArg(aArgs, 'line'),1186 generatedColumn: util.getArg(aArgs, 'column')1187 };1188 var mapping = this._findMapping(needle,1189 this._generatedMappings,1190 "generatedLine",1191 "generatedColumn",1192 util.compareByGeneratedPositions);1193 if (mapping) {1194 var source = util.getArg(mapping, 'source', null);1195 if (source && this.sourceRoot) {1196 source = util.join(this.sourceRoot, source);1197 }1198 return {1199 source: source,1200 line: util.getArg(mapping, 'originalLine', null),1201 column: util.getArg(mapping, 'originalColumn', null),1202 name: util.getArg(mapping, 'name', null)1203 };1204 }1205 return {1206 source: null,1207 line: null,1208 column: null,1209 name: null1210 };1211 };1212 /**1213 * Returns the original source content. The only argument is the url of the1214 * original source file. Returns null if no original source content is1215 * availible.1216 */1217 SourceMapConsumer.prototype.sourceContentFor =1218 function SourceMapConsumer_sourceContentFor(aSource) {1219 if (!this.sourcesContent) {1220 return null;1221 }1222 if (this.sourceRoot) {1223 aSource = util.relative(this.sourceRoot, aSource);1224 }1225 if (this._sources.has(aSource)) {1226 return this.sourcesContent[this._sources.indexOf(aSource)];1227 }1228 var url;1229 if (this.sourceRoot1230 && (url = util.urlParse(this.sourceRoot))) {1231 // XXX: file:// URIs and absolute paths lead to unexpected behavior for1232 // many users. We can help them out when they expect file:// URIs to1233 // behave like it would if they were running a local HTTP server. See1234 // https://bugzilla.mozilla.org/show_bug.cgi?id=885597.1235 var fileUriAbsPath = aSource.replace(/^file:\/\//, "");1236 if (url.scheme == "file"1237 && this._sources.has(fileUriAbsPath)) {1238 return this.sourcesContent[this._sources.indexOf(fileUriAbsPath)]1239 }1240 if ((!url.path || url.path == "/")1241 && this._sources.has("/" + aSource)) {1242 return this.sourcesContent[this._sources.indexOf("/" + aSource)];1243 }1244 }1245 throw new Error('"' + aSource + '" is not in the SourceMap.');1246 };1247 /**1248 * Returns the generated line and column information for the original source,1249 * line, and column positions provided. The only argument is an object with1250 * the following properties:1251 *1252 * - source: The filename of the original source.1253 * - line: The line number in the original source.1254 * - column: The column number in the original source.1255 *1256 * and an object is returned with the following properties:1257 *1258 * - line: The line number in the generated source, or null.1259 * - column: The column number in the generated source, or null.1260 */1261 SourceMapConsumer.prototype.generatedPositionFor =1262 function SourceMapConsumer_generatedPositionFor(aArgs) {1263 var needle = {1264 source: util.getArg(aArgs, 'source'),1265 originalLine: util.getArg(aArgs, 'line'),1266 originalColumn: util.getArg(aArgs, 'column')1267 };1268 if (this.sourceRoot) {1269 needle.source = util.relative(this.sourceRoot, needle.source);1270 }1271 var mapping = this._findMapping(needle,1272 this._originalMappings,1273 "originalLine",1274 "originalColumn",1275 util.compareByOriginalPositions);1276 if (mapping) {1277 return {1278 line: util.getArg(mapping, 'generatedLine', null),1279 column: util.getArg(mapping, 'generatedColumn', null)1280 };1281 }1282 return {1283 line: null,1284 column: null1285 };1286 };1287 SourceMapConsumer.GENERATED_ORDER = 1;1288 SourceMapConsumer.ORIGINAL_ORDER = 2;1289 /**1290 * Iterate over each mapping between an original source/line/column and a1291 * generated line/column in this source map.1292 *1293 * @param Function aCallback1294 * The function that is called with each mapping.1295 * @param Object aContext1296 * Optional. If specified, this object will be the value of `this` every1297 * time that `aCallback` is called.1298 * @param aOrder1299 * Either `SourceMapConsumer.GENERATED_ORDER` or1300 * `SourceMapConsumer.ORIGINAL_ORDER`. Specifies whether you want to1301 * iterate over the mappings sorted by the generated file's line/column1302 * order or the original's source/line/column order, respectively. Defaults to1303 * `SourceMapConsumer.GENERATED_ORDER`.1304 */1305 SourceMapConsumer.prototype.eachMapping =1306 function SourceMapConsumer_eachMapping(aCallback, aContext, aOrder) {1307 var context = aContext || null;1308 var order = aOrder || SourceMapConsumer.GENERATED_ORDER;1309 var mappings;1310 switch (order) {1311 case SourceMapConsumer.GENERATED_ORDER:1312 mappings = this._generatedMappings;1313 break;1314 case SourceMapConsumer.ORIGINAL_ORDER:1315 mappings = this._originalMappings;1316 break;1317 default:1318 throw new Error("Unknown order of iteration.");1319 }1320 var sourceRoot = this.sourceRoot;1321 mappings.map(function (mapping) {1322 var source = mapping.source;1323 if (source && sourceRoot) {1324 source = util.join(sourceRoot, source);1325 }1326 return {1327 source: source,1328 generatedLine: mapping.generatedLine,1329 generatedColumn: mapping.generatedColumn,1330 originalLine: mapping.originalLine,1331 originalColumn: mapping.originalColumn,1332 name: mapping.name1333 };1334 }).forEach(aCallback, context);1335 };1336 exports.SourceMapConsumer = SourceMapConsumer;1337});1338/* -*- Mode: js; js-indent-level: 2; -*- */1339/*1340 * Copyright 2011 Mozilla Foundation and contributors1341 * Licensed under the New BSD license. See LICENSE or:1342 * http://opensource.org/licenses/BSD-3-Clause1343 */1344define('source-map/binary-search', ['require', 'exports', 'module' , ], function(require, exports, module) {1345 /**1346 * Recursive implementation of binary search.1347 *1348 * @param aLow Indices here and lower do not contain the needle.1349 * @param aHigh Indices here and higher do not contain the needle.1350 * @param aNeedle The element being searched for.1351 * @param aHaystack The non-empty array being searched.1352 * @param aCompare Function which takes two elements and returns -1, 0, or 1.1353 */1354 function recursiveSearch(aLow, aHigh, aNeedle, aHaystack, aCompare) {1355 // This function terminates when one of the following is true:1356 //1357 // 1. We find the exact element we are looking for.1358 //1359 // 2. We did not find the exact element, but we can return the next1360 // closest element that is less than that element.1361 //1362 // 3. We did not find the exact element, and there is no next-closest1363 // element which is less than the one we are searching for, so we1364 // return null.1365 var mid = Math.floor((aHigh - aLow) / 2) + aLow;1366 var cmp = aCompare(aNeedle, aHaystack[mid], true);1367 if (cmp === 0) {1368 // Found the element we are looking for.1369 return aHaystack[mid];1370 }1371 else if (cmp > 0) {1372 // aHaystack[mid] is greater than our needle.1373 if (aHigh - mid > 1) {1374 // The element is in the upper half.1375 return recursiveSearch(mid, aHigh, aNeedle, aHaystack, aCompare);1376 }1377 // We did not find an exact match, return the next closest one1378 // (termination case 2).1379 return aHaystack[mid];1380 }1381 else {1382 // aHaystack[mid] is less than our needle.1383 if (mid - aLow > 1) {1384 // The element is in the lower half.1385 return recursiveSearch(aLow, mid, aNeedle, aHaystack, aCompare);1386 }1387 // The exact needle element was not found in this haystack. Determine if1388 // we are in termination case (2) or (3) and return the appropriate thing.1389 return aLow < 01390 ? null1391 : aHaystack[aLow];1392 }1393 }1394 /**1395 * This is an implementation of binary search which will always try and return1396 * the next lowest value checked if there is no exact hit. This is because1397 * mappings between original and generated line/col pairs are single points,1398 * and there is an implicit region between each of them, so a miss just means1399 * that you aren't on the very start of a region.1400 *1401 * @param aNeedle The element you are looking for.1402 * @param aHaystack The array that is being searched.1403 * @param aCompare A function which takes the needle and an element in the1404 * array and returns -1, 0, or 1 depending on whether the needle is less1405 * than, equal to, or greater than the element, respectively.1406 */1407 exports.search = function search(aNeedle, aHaystack, aCompare) {1408 return aHaystack.length > 01409 ? recursiveSearch(-1, aHaystack.length, aNeedle, aHaystack, aCompare)1410 : null;1411 };1412});1413/* -*- Mode: js; js-indent-level: 2; -*- */1414/*1415 * Copyright 2011 Mozilla Foundation and contributors1416 * Licensed under the New BSD license. See LICENSE or:1417 * http://opensource.org/licenses/BSD-3-Clause1418 */1419define('source-map/source-node', ['require', 'exports', 'module' , 'source-map/source-map-generator', 'source-map/util'], function(require, exports, module) {1420 var SourceMapGenerator = require('./source-map-generator').SourceMapGenerator;1421 var util = require('./util');1422 /**1423 * SourceNodes provide a way to abstract over interpolating/concatenating1424 * snippets of generated JavaScript source code while maintaining the line and1425 * column information associated with the original source code.1426 *1427 * @param aLine The original line number.1428 * @param aColumn The original column number.1429 * @param aSource The original source's filename.1430 * @param aChunks Optional. An array of strings which are snippets of1431 * generated JS, or other SourceNodes.1432 * @param aName The original identifier.1433 */1434 function SourceNode(aLine, aColumn, aSource, aChunks, aName) {1435 this.children = [];1436 this.sourceContents = {};1437 this.line = aLine === undefined ? null : aLine;1438 this.column = aColumn === undefined ? null : aColumn;1439 this.source = aSource === undefined ? null : aSource;1440 this.name = aName === undefined ? null : aName;1441 if (aChunks != null) this.add(aChunks);1442 }1443 /**1444 * Creates a SourceNode from generated code and a SourceMapConsumer.1445 *1446 * @param aGeneratedCode The generated code1447 * @param aSourceMapConsumer The SourceMap for the generated code1448 */1449 SourceNode.fromStringWithSourceMap =1450 function SourceNode_fromStringWithSourceMap(aGeneratedCode, aSourceMapConsumer) {1451 // The SourceNode we want to fill with the generated code1452 // and the SourceMap1453 var node = new SourceNode();1454 // The generated code1455 // Processed fragments are removed from this array.1456 var remainingLines = aGeneratedCode.split('\n');1457 // We need to remember the position of "remainingLines"1458 var lastGeneratedLine = 1, lastGeneratedColumn = 0;1459 // The generate SourceNodes we need a code range.1460 // To extract it current and last mapping is used.1461 // Here we store the last mapping.1462 var lastMapping = null;1463 aSourceMapConsumer.eachMapping(function (mapping) {1464 if (lastMapping === null) {1465 // We add the generated code until the first mapping1466 // to the SourceNode without any mapping.1467 // Each line is added as separate string.1468 while (lastGeneratedLine < mapping.generatedLine) {1469 node.add(remainingLines.shift() + "\n");1470 lastGeneratedLine++;1471 }1472 if (lastGeneratedColumn < mapping.generatedColumn) {1473 var nextLine = remainingLines[0];1474 node.add(nextLine.substr(0, mapping.generatedColumn));1475 remainingLines[0] = nextLine.substr(mapping.generatedColumn);1476 lastGeneratedColumn = mapping.generatedColumn;1477 }1478 } else {1479 // We add the code from "lastMapping" to "mapping":1480 // First check if there is a new line in between.1481 if (lastGeneratedLine < mapping.generatedLine) {1482 var code = "";1483 // Associate full lines with "lastMapping"1484 do {1485 code += remainingLines.shift() + "\n";1486 lastGeneratedLine++;1487 lastGeneratedColumn = 0;1488 } while (lastGeneratedLine < mapping.generatedLine);1489 // When we reached the correct line, we add code until we1490 // reach the correct column too.1491 if (lastGeneratedColumn < mapping.generatedColumn) {1492 var nextLine = remainingLines[0];1493 code += nextLine.substr(0, mapping.generatedColumn);1494 remainingLines[0] = nextLine.substr(mapping.generatedColumn);1495 lastGeneratedColumn = mapping.generatedColumn;1496 }1497 // Create the SourceNode.1498 addMappingWithCode(lastMapping, code);1499 } else {1500 // There is no new line in between.1501 // Associate the code between "lastGeneratedColumn" and1502 // "mapping.generatedColumn" with "lastMapping"1503 var nextLine = remainingLines[0];1504 var code = nextLine.substr(0, mapping.generatedColumn -1505 lastGeneratedColumn);1506 remainingLines[0] = nextLine.substr(mapping.generatedColumn -1507 lastGeneratedColumn);1508 lastGeneratedColumn = mapping.generatedColumn;1509 addMappingWithCode(lastMapping, code);1510 }1511 }1512 lastMapping = mapping;1513 }, this);1514 // We have processed all mappings.1515 // Associate the remaining code in the current line with "lastMapping"1516 // and add the remaining lines without any mapping1517 addMappingWithCode(lastMapping, remainingLines.join("\n"));1518 // Copy sourcesContent into SourceNode1519 aSourceMapConsumer.sources.forEach(function (sourceFile) {1520 var content = aSourceMapConsumer.sourceContentFor(sourceFile);1521 if (content) {1522 node.setSourceContent(sourceFile, content);1523 }1524 });1525 return node;1526 function addMappingWithCode(mapping, code) {1527 if (mapping === null || mapping.source === undefined) {1528 node.add(code);1529 } else {1530 node.add(new SourceNode(mapping.originalLine,1531 mapping.originalColumn,1532 mapping.source,1533 code,1534 mapping.name));1535 }1536 }1537 };1538 /**1539 * Add a chunk of generated JS to this source node.1540 *1541 * @param aChunk A string snippet of generated JS code, another instance of1542 * SourceNode, or an array where each member is one of those things.1543 */1544 SourceNode.prototype.add = function SourceNode_add(aChunk) {1545 if (Array.isArray(aChunk)) {1546 aChunk.forEach(function (chunk) {1547 this.add(chunk);1548 }, this);1549 }1550 else if (aChunk instanceof SourceNode || typeof aChunk === "string") {1551 if (aChunk) {1552 this.children.push(aChunk);1553 }1554 }1555 else {1556 throw new TypeError(1557 "Expected a SourceNode, string, or an array of SourceNodes and strings. Got " + aChunk1558 );1559 }1560 return this;1561 };1562 /**1563 * Add a chunk of generated JS to the beginning of this source node.1564 *1565 * @param aChunk A string snippet of generated JS code, another instance of1566 * SourceNode, or an array where each member is one of those things.1567 */1568 SourceNode.prototype.prepend = function SourceNode_prepend(aChunk) {1569 if (Array.isArray(aChunk)) {1570 for (var i = aChunk.length-1; i >= 0; i--) {1571 this.prepend(aChunk[i]);1572 }1573 }1574 else if (aChunk instanceof SourceNode || typeof aChunk === "string") {1575 this.children.unshift(aChunk);1576 }1577 else {1578 throw new TypeError(1579 "Expected a SourceNode, string, or an array of SourceNodes and strings. Got " + aChunk1580 );1581 }1582 return this;1583 };1584 /**1585 * Walk over the tree of JS snippets in this node and its children. The1586 * walking function is called once for each snippet of JS and is passed that1587 * snippet and the its original associated source's line/column location.1588 *1589 * @param aFn The traversal function.1590 */1591 SourceNode.prototype.walk = function SourceNode_walk(aFn) {1592 var chunk;1593 for (var i = 0, len = this.children.length; i < len; i++) {1594 chunk = this.children[i];1595 if (chunk instanceof SourceNode) {1596 chunk.walk(aFn);1597 }1598 else {1599 if (chunk !== '') {1600 aFn(chunk, { source: this.source,1601 line: this.line,1602 column: this.column,1603 name: this.name });1604 }1605 }1606 }1607 };1608 /**1609 * Like `String.prototype.join` except for SourceNodes. Inserts `aStr` between1610 * each of `this.children`.1611 *1612 * @param aSep The separator.1613 */1614 SourceNode.prototype.join = function SourceNode_join(aSep) {1615 var newChildren;1616 var i;1617 var len = this.children.length;1618 if (len > 0) {1619 newChildren = [];1620 for (i = 0; i < len-1; i++) {1621 newChildren.push(this.children[i]);1622 newChildren.push(aSep);1623 }1624 newChildren.push(this.children[i]);1625 this.children = newChildren;1626 }1627 return this;1628 };1629 /**1630 * Call String.prototype.replace on the very right-most source snippet. Useful1631 * for trimming whitespace from the end of a source node, etc.1632 *1633 * @param aPattern The pattern to replace.1634 * @param aReplacement The thing to replace the pattern with.1635 */1636 SourceNode.prototype.replaceRight = function SourceNode_replaceRight(aPattern, aReplacement) {1637 var lastChild = this.children[this.children.length - 1];1638 if (lastChild instanceof SourceNode) {1639 lastChild.replaceRight(aPattern, aReplacement);1640 }1641 else if (typeof lastChild === 'string') {1642 this.children[this.children.length - 1] = lastChild.replace(aPattern, aReplacement);1643 }1644 else {1645 this.children.push(''.replace(aPattern, aReplacement));1646 }1647 return this;1648 };1649 /**1650 * Set the source content for a source file. This will be added to the SourceMapGenerator1651 * in the sourcesContent field.1652 *1653 * @param aSourceFile The filename of the source file1654 * @param aSourceContent The content of the source file1655 */1656 SourceNode.prototype.setSourceContent =1657 function SourceNode_setSourceContent(aSourceFile, aSourceContent) {1658 this.sourceContents[util.toSetString(aSourceFile)] = aSourceContent;1659 };1660 /**1661 * Walk over the tree of SourceNodes. The walking function is called for each1662 * source file content and is passed the filename and source content.1663 *1664 * @param aFn The traversal function.1665 */1666 SourceNode.prototype.walkSourceContents =1667 function SourceNode_walkSourceContents(aFn) {1668 for (var i = 0, len = this.children.length; i < len; i++) {1669 if (this.children[i] instanceof SourceNode) {1670 this.children[i].walkSourceContents(aFn);1671 }1672 }1673 var sources = Object.keys(this.sourceContents);1674 for (var i = 0, len = sources.length; i < len; i++) {1675 aFn(util.fromSetString(sources[i]), this.sourceContents[sources[i]]);1676 }1677 };1678 /**1679 * Return the string representation of this source node. Walks over the tree1680 * and concatenates all the various snippets together to one string.1681 */1682 SourceNode.prototype.toString = function SourceNode_toString() {1683 var str = "";1684 this.walk(function (chunk) {1685 str += chunk;1686 });1687 return str;1688 };1689 /**1690 * Returns the string representation of this source node along with a source1691 * map.1692 */1693 SourceNode.prototype.toStringWithSourceMap = function SourceNode_toStringWithSourceMap(aArgs) {1694 var generated = {1695 code: "",1696 line: 1,1697 column: 01698 };1699 var map = new SourceMapGenerator(aArgs);1700 var sourceMappingActive = false;1701 var lastOriginalSource = null;1702 var lastOriginalLine = null;1703 var lastOriginalColumn = null;1704 var lastOriginalName = null;1705 this.walk(function (chunk, original) {1706 generated.code += chunk;1707 if (original.source !== null1708 && original.line !== null1709 && original.column !== null) {1710 if(lastOriginalSource !== original.source1711 || lastOriginalLine !== original.line1712 || lastOriginalColumn !== original.column1713 || lastOriginalName !== original.name) {1714 map.addMapping({1715 source: original.source,1716 original: {1717 line: original.line,1718 column: original.column1719 },1720 generated: {1721 line: generated.line,1722 column: generated.column1723 },1724 name: original.name1725 });1726 }1727 lastOriginalSource = original.source;1728 lastOriginalLine = original.line;1729 lastOriginalColumn = original.column;1730 lastOriginalName = original.name;1731 sourceMappingActive = true;1732 } else if (sourceMappingActive) {1733 map.addMapping({1734 generated: {1735 line: generated.line,1736 column: generated.column1737 }1738 });1739 lastOriginalSource = null;1740 sourceMappingActive = false;1741 }1742 chunk.split('').forEach(function (ch) {1743 if (ch === '\n') {1744 generated.line++;1745 generated.column = 0;1746 } else {1747 generated.column++;1748 }1749 });1750 });1751 this.walkSourceContents(function (sourceFile, sourceContent) {1752 map.setSourceContent(sourceFile, sourceContent);1753 });1754 return { code: generated.code, map: map };1755 };1756 exports.SourceNode = SourceNode;1757});1758/* -*- Mode: js; js-indent-level: 2; -*- */1759///////////////////////////////////////////////////////////////////////////////1760this.sourceMap = {1761 SourceMapConsumer: require('source-map/source-map-consumer').SourceMapConsumer,1762 SourceMapGenerator: require('source-map/source-map-generator').SourceMapGenerator,1763 SourceNode: require('source-map/source-node').SourceNode1764};...
SearchSourceSettings.js
Source:SearchSourceSettings.js
1///////////////////////////////////////////////////////////////////////////2// Copyright © Esri. All Rights Reserved.3//4// Licensed under the Apache License Version 2.0 (the 'License');5// you may not use this file except in compliance with the License.6// You may obtain a copy of the License at7//8// http://www.apache.org/licenses/LICENSE-2.09//10// Unless required by applicable law or agreed to in writing, software11// distributed under the License is distributed on an 'AS IS' BASIS,12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.13// See the License for the specific language governing permissions and14// limitations under the License.15///////////////////////////////////////////////////////////////////////////16define([17 'dojo/_base/declare',18 'jimu/BaseWidgetSetting',19 'dijit/_WidgetsInTemplateMixin',20 'dojo/Evented',21 'dojo/text!./SearchSourceSettings.html',22 'dojo/_base/html',23 'jimu/dijit/SimpleTable',24 './QuerySourceSetting',25 './LocatorSourceSetting',26 'jimu/LayerInfos/LayerInfos',27 '../searchSourceUtils',28 'jimu/utils',29 'dojo/when',30 'esri/lang',31 'dojo/_base/lang',32 'dojo/_base/array',33 'dojo/query',34 'dojo/on',35 'dojo/dom-class',36 'jimu/dijit/CheckBox',37 'dojo/domReady!'38], function (39 declare,40 BaseWidgetSetting,41 _WidgetsInTemplateMixin,42 Evented,43 SearchSourceSettingsTemplate,44 html,45 SimpleTable,46 QuerySourceSetting,47 LocatorSourceSetting,48 LayerInfos,49 utils,50 jimuUtils,51 when,52 esriLang,53 lang,54 array,55 query,56 on,57 domClass,58 CheckBox59) {60 return declare([BaseWidgetSetting, _WidgetsInTemplateMixin, Evented], {61 baseClass: 'jimu-widget-screening-search-source-settings',62 templateString: SearchSourceSettingsTemplate,63 startup: function () {64 this.inherited(arguments);65 },66 postCreate: function () {67 this.inherited(arguments);68 this.own(on(this.menuItemClickNode, 'click', lang.hitch(this, this._onMenuItemClick)));69 this._createSourceListTable();70 //create checkbox for show infoWindow on select71 this.showInfoWindowOnSelect = new CheckBox({72 checked: false,73 label: this.nls.searchSourceSetting.generalSettingCheckboxLabel74 }, this.showInfoWindowOnSelectNode);75 if (!(this.config && this.config.sources)) {76 this.config.sources = [];77 }78 LayerInfos.getInstance(this.map, this.map.itemInfo)79 .then(lang.hitch(this, function (layerInfosObj) {80 this.layerInfosObj = layerInfosObj;81 utils.setMap(this.map);82 utils.setLayerInfosObj(this.layerInfosObj);83 utils.setAppConfig(this.appConfig);84 when(utils.getConfigInfo(this.config)).then(lang.hitch(this, this._loadConfig));85 }));86 },87 /**88 * This function is to load configuration89 * @param{object} contains config90 * @memberOf Screening/setting/SearchSourceSettings91 */92 _loadConfig: function (config) {93 if (!this.domNode) {94 return;95 }96 this.setConfig(config);97 },98 /**99 * This function is to set configured values to respective components100 * @param{object} contains config101 * @memberOf Screening/setting/SearchSourceSettings102 */103 setConfig: function (config) {104 this.config = config;105 var sources = config.sources;106 this.allPlaceholder.set('value', jimuUtils.stripHTML(this.config.allPlaceholder));107 this.showInfoWindowOnSelect.setValue(108 esriLang.isDefined(this.config.showInfoWindowOnSelect) ?109 !!this.config.showInfoWindowOnSelect : true);110 array.forEach(sources, lang.hitch(this, function (source, index) {111 var addResult = this.sourceList.addRow({112 name: source.name || ""113 });114 if (addResult && addResult.success) {115 this._setRelatedConfig(addResult.tr, source);116 if (index === 0) {117 var firstTr = addResult.tr;118 setTimeout(lang.hitch(this, function () {119 this.sourceList.selectRow(addResult.tr);120 firstTr = null;121 }), 100);122 }123 } else {124 console.error("add row failed ", addResult);125 }126 }));127 },128 /**129 * Gets the config updates by user, validates and returns the config object130 * @memberOf Screening/setting/SearchSourceSettings131 */132 getConfig: function () {133 if (this._currentSourceSetting) {134 if (this._currentSourceSetting.isValidConfig()) {135 this._closeSourceSetting();136 } else {137 return null;138 }139 }140 var config = {141 allPlaceholder: jimuUtils.stripHTML(this.allPlaceholder.get('value')),142 showInfoWindowOnSelect: this.showInfoWindowOnSelect.checked143 };144 var trs = this.sourceList.getRows();145 var sources = [];146 array.forEach(trs, lang.hitch(this, function (tr) {147 var source = this._getRelatedConfig(tr);148 delete source._definition;149 this._removeRelatedConfig(tr);150 sources.push(source);151 }));152 config.sources = sources;153 return config;154 },155 /**156 * Reset search configuration UI157 * @memberOf Screening/setting/SearchSourceSettings158 */159 destroy: function () {160 utils.setMap(null);161 utils.setLayerInfosObj(null);162 utils.setAppConfig(null);163 this.inherited(arguments);164 },165 /**166 * Set value of placeholder on blur167 * @memberOf Screening/setting/SearchSourceSettings168 */169 _onAllPlaceholderBlur: function () {170 this.allPlaceholder.set('value', jimuUtils.stripHTML(this.allPlaceholder.get('value')));171 },172 /**173 * Create source list table174 * @memberOf Screening/setting/SearchSourceSettings175 */176 _createSourceListTable: function () {177 this.sourceList = new SimpleTable({178 autoHeight: false,179 selectable: true,180 fields: [{181 name: "name",182 title: this.nls.common.name,183 width: "auto",184 type: "text",185 editable: false186 }, {187 name: "actions",188 title: "",189 width: "70px",190 type: "actions",191 actions: ["up", "down", "delete"]192 }]193 }, this.sourceList);194 html.setStyle(this.sourceList.domNode, 'height', '100%');195 this.sourceList.startup();196 this.own(on(this.sourceList, 'row-select', lang.hitch(this, this._onSourceItemSelected)));197 this.own(on(this.sourceList, 'row-delete', lang.hitch(this, this._onSourceItemRemoved)));198 },199 /**200 * on row delete from source list table201 * @param{node} contains table row202 * @memberOf Screening/setting/SearchSourceSettings203 */204 _onSourceItemRemoved: function (tr) {205 if (!this._currentSourceSetting) {206 return;207 }208 var currentTr = this._currentSourceSetting.getRelatedTr();209 if (currentTr === tr) {210 this._currentSourceSetting.destroy();211 this._currentSourceSetting = null;212 }213 },214 /**215 * on row selection of source list table216 * @param{node} contains table row217 * @memberOf Screening/setting/SearchSourceSettings218 */219 _onSourceItemSelected: function (tr) {220 var config = this._getRelatedConfig(tr);221 var currentTr = this._currentSourceSetting && this._currentSourceSetting.tr;222 if (!config || tr === currentTr) {223 return;224 }225 // check fields226 if (this._currentSourceSetting && !this._currentSourceSetting.isValidConfig()) {227 this._currentSourceSetting.showValidationTip();228 this.sourceList.selectRow(currentTr);229 return;230 }231 //Remove extra height required for localSearch.232 //This will required when prev selected locator has local search enable233 domClass.remove(this.searchSources, "esriCTSourcesExtraHeight");234 if (config.type === "query") {235 this._createNewQuerySourceSettingFromSourceList(config, config._definition || {}, tr);236 } else if (config.type === "locator") {237 this._createNewLocatorSourceSettingFromSourceList(config, config._definition || {}, tr);238 }239 },240 /**241 * Set related configuration to widget configuration242 * @param{node} contains table row243 * @param{object} contains table source244 * @memberOf Screening/setting/SearchSourceSettings245 */246 _setRelatedConfig: function (tr, source) {247 query(tr).data('config', lang.clone(source));248 },249 /**250 * Get related configuration from widget configuration251 * @param{node} contains table row252 * @memberOf Screening/setting/SearchSourceSettings253 */254 _getRelatedConfig: function (tr) {255 return query(tr).data('config')[0];256 },257 /**258 * Remove related configuration from widget configuration259 * @param{node} contains table row260 * @memberOf Screening/setting/SearchSourceSettings261 */262 _removeRelatedConfig: function (tr) {263 return query(tr).removeData('config');264 },265 /**266 * On menu item click267 * @param{object} contains event information268 * @memberOf Screening/setting/SearchSourceSettings269 */270 _onMenuItemClick: function (evt) {271 var itemType = evt && evt.target && html.getAttr(evt.target, "type");272 //if current settings are not valid then emit invalid settings event else create new source273 if (this._currentSourceSetting && !this._currentSourceSetting.isValidConfig()) {274 this.emit("invalid-source-setting");275 } else {276 //Remove extra height required for localSearch.277 //This will required when prev selected locator has local search enable278 domClass.remove(this.searchSources, "esriCTSourcesExtraHeight");279 if (itemType === "locator") {280 this._addNewLocator();281 } else if (itemType === "query") {282 this._addNewQuerySource();283 }284 }285 },286 /**287 * Add new locator288 * @memberOf Screening/setting/SearchSourceSettings289 */290 _addNewLocator: function () {291 this._createNewLocatorSourceSettingFromMenuItem({}, {});292 },293 /**294 * Add new query source295 * @memberOf Screening/setting/SearchSourceSettings296 */297 _addNewQuerySource: function () {298 this._createNewQuerySourceSettingFromMenuItem({}, {});299 },300 /**301 * Create new locator source setting from menu item302 * @param{object} contains setting303 * @param{string} contains definition304 * @memberOf Screening/setting/SearchSourceSettings305 */306 _createNewLocatorSourceSettingFromMenuItem: function (setting, definition) {307 var locatorSetting = new LocatorSourceSetting({308 nls: lang.mixin(this.nls.searchSourceSetting, window.jimuNls.units),309 map: this.map310 });311 locatorSetting.setDefinition(definition);312 locatorSetting.setConfig({313 url: setting.url || "",314 name: setting.name || "",315 singleLineFieldName: setting.singleLineFieldName || "",316 placeholder: setting.placeholder || "",317 countryCode: setting.countryCode || "",318 maxSuggestions: setting.maxSuggestions || 6,319 maxResults: setting.maxResults || 6,320 searchInCurrentMapExtent: !!setting.searchInCurrentMapExtent,321 type: "locator"322 });323 locatorSetting._openLocatorChooser();324 locatorSetting.own(325 on(locatorSetting, 'select-locator-url-ok', lang.hitch(this, function (item) {326 var addResult = this.sourceList.addRow({327 name: item.name || "New Geocoder"328 }, this.sourceList.getRows().length);329 if (addResult && addResult.success) {330 if (this._currentSourceSetting) {331 this._closeSourceSetting();332 }333 locatorSetting.setRelatedTr(addResult.tr);334 locatorSetting.placeAt(this.sourceSettingNode);335 this.sourceList.selectRow(addResult.tr);336 this._currentSourceSetting = locatorSetting;337 }338 }))339 );340 locatorSetting.own(341 on(locatorSetting, 'reselect-locator-url-ok', lang.hitch(this, function (item) {342 var tr = this._currentSourceSetting.getRelatedTr();343 this.sourceList.editRow(tr, {344 name: item.name345 });346 }))347 );348 locatorSetting.own(349 on(locatorSetting, 'select-locator-url-cancel', lang.hitch(this, function () {350 if (this._currentSourceSetting !== locatorSetting) {// locator doesn't display in UI351 locatorSetting.destroy();352 locatorSetting = null;353 }354 }))355 );356 },357 /**358 * Create new locator source setting from Source List359 * @param{object} contains setting360 * @param{string} contains definition361 * @param{node} contains relatedTr362 * @memberOf Screening/setting/SearchSourceSettings363 */364 _createNewLocatorSourceSettingFromSourceList: function (setting, definition, relatedTr) {365 if (this._currentSourceSetting) {366 this._closeSourceSetting();367 }368 this._currentSourceSetting = new LocatorSourceSetting({369 nls: lang.mixin(this.nls.searchSourceSetting, window.jimuNls.units),370 map: this.map371 });372 this._currentSourceSetting.own(373 on(this._currentSourceSetting, 'enable-local-search', lang.hitch(this, function () {374 domClass.add(this.searchSources, "esriCTSourcesExtraHeight");375 }))376 );377 this._currentSourceSetting.own(378 on(this._currentSourceSetting, 'disable-local-search', lang.hitch(this, function () {379 domClass.remove(this.searchSources, "esriCTSourcesExtraHeight");380 }))381 );382 this._currentSourceSetting.setDefinition(definition);383 this._currentSourceSetting.setConfig({384 url: setting.url || "",385 name: setting.name || "",386 singleLineFieldName: setting.singleLineFieldName || "",387 placeholder: setting.placeholder || "",388 countryCode: setting.countryCode || "",389 maxSuggestions: setting.maxSuggestions || 6,390 maxResults: setting.maxResults || 6,391 searchInCurrentMapExtent: !!setting.searchInCurrentMapExtent,392 enableLocalSearch: !!setting.enableLocalSearch,393 localSearchMinScale: setting.localSearchMinScale,394 localSearchDistance: setting.localSearchDistance,395 type: "locator"396 });397 this._currentSourceSetting.setRelatedTr(relatedTr);398 this._currentSourceSetting.placeAt(this.sourceSettingNode);399 this._currentSourceSetting.own(400 on(this._currentSourceSetting,401 'reselect-locator-url-ok',402 lang.hitch(this, function (item) {403 var tr = this._currentSourceSetting.getRelatedTr();404 this.sourceList.editRow(tr, {405 name: item.name406 });407 }))408 );409 },410 /**411 * Close source setting412 * @memberOf Screening/setting/SearchSourceSettings413 */414 _closeSourceSetting: function () {415 var tr = this._currentSourceSetting.getRelatedTr();416 var source = this._currentSourceSetting.getConfig();417 source._definition = this._currentSourceSetting.getDefinition();418 this._setRelatedConfig(tr, source);419 this.sourceList.editRow(tr, {420 name: source.name421 });422 this._currentSourceSetting.destroy();423 },424 /**425 * Create new query source setting from menu item426 * @param{object} contains setting427 * @param{string} contains definition428 * @memberOf Screening/setting/SearchSourceSettings429 */430 _createNewQuerySourceSettingFromMenuItem: function (setting, definition) {431 var querySetting = new QuerySourceSetting({432 nls: this.nls.searchSourceSetting,433 map: this.map,434 appConfig: this.appConfig435 });436 querySetting.setDefinition(definition);437 querySetting.setConfig({438 url: setting.url,439 name: setting.name || "",440 layerId: setting.layerId,441 placeholder: setting.placeholder || "",442 searchFields: setting.searchFields || [],443 displayField: setting.displayField || definition.displayField || "",444 exactMatch: !!setting.exactMatch,445 maxSuggestions: setting.maxSuggestions || 6,446 maxResults: setting.maxResults || 6,447 searchInCurrentMapExtent: !!setting.searchInCurrentMapExtent,448 type: "query"449 });450 querySetting._openQuerySourceChooser();451 querySetting.own(452 on(querySetting, 'select-query-source-ok', lang.hitch(this, function (item) {453 var addResult = this.sourceList.addRow({454 name: item.name455 }, 0);456 if (addResult && addResult.success) {457 if (this._currentSourceSetting) {458 this._closeSourceSetting();459 }460 querySetting.setRelatedTr(addResult.tr);461 querySetting.placeAt(this.sourceSettingNode);462 this.sourceList.selectRow(addResult.tr);463 this._currentSourceSetting = querySetting;464 }465 }))466 );467 querySetting.own(468 on(querySetting, 'reselect-query-source-ok', lang.hitch(this, function (item) {469 var tr = this._currentSourceSetting.getRelatedTr();470 this.sourceList.editRow(tr, {471 name: item.name472 });473 }))474 );475 querySetting.own(476 on(querySetting, 'select-query-source-cancel', lang.hitch(this, function () {477 if (this._currentSourceSetting !== querySetting) {// query source doesn't display in UI478 querySetting.destroy();479 querySetting = null;480 }481 }))482 );483 },484 /**485 * Create new query source setting from source list486 * @param{object} contains setting487 * @param{string} contains definition488 * @param{node} contains relatedTr489 * @memberOf Screening/setting/SearchSourceSettings490 */491 _createNewQuerySourceSettingFromSourceList: function (setting, definition, relatedTr) {492 if (this._currentSourceSetting) {493 this._closeSourceSetting();494 }495 this._currentSourceSetting = new QuerySourceSetting({496 nls: this.nls.searchSourceSetting,497 map: this.map,498 appConfig: this.appConfig499 });500 this._currentSourceSetting.placeAt(this.sourceSettingNode);501 this._currentSourceSetting.setDefinition(definition);502 this._currentSourceSetting.setConfig({503 url: setting.url,504 name: setting.name || "",505 layerId: setting.layerId,506 placeholder: setting.placeholder || "",507 searchFields: setting.searchFields || [],508 displayField: setting.displayField || definition.displayField || "",509 exactMatch: !!setting.exactMatch,510 maxSuggestions: setting.maxSuggestions || 6,511 maxResults: setting.maxResults || 6,512 searchInCurrentMapExtent: !!setting.searchInCurrentMapExtent,513 type: "query"514 });515 this._currentSourceSetting.setRelatedTr(relatedTr);516 this._currentSourceSetting.own(517 on(this._currentSourceSetting, 'reselect-query-source', lang.hitch(this, function (item) {518 var tr = this._currentSourceSetting.getRelatedTr();519 this.sourceList.editRow(tr, {520 name: item.name521 });522 }))523 );524 }525 });...
MeasurementService.js
Source:MeasurementService.js
1import log from '../../log';2import guid from '../../utils/guid';3import pubSubServiceInterface from '../_shared/pubSubServiceInterface';4/**5 * Measurement source schema6 *7 * @typedef {Object} MeasurementSource8 * @property {number} id -9 * @property {string} name -10 * @property {string} version -11 */12/**13 * Measurement schema14 *15 * @typedef {Object} Measurement16 * @property {number} id -17 * @property {string} SOPInstanceUID -18 * @property {string} FrameOfReferenceUID -19 * @property {string} referenceSeriesUID -20 * @property {string} label -21 * @property {string} description -22 * @property {string} type -23 * @property {string} unit -24 * @property {number} area -25 * @property {Array} points -26 * @property {MeasurementSource} source -27 */28/* Measurement schema keys for object validation. */29const MEASUREMENT_SCHEMA_KEYS = [30 'id',31 'SOPInstanceUID',32 'FrameOfReferenceUID',33 'referenceStudyUID',34 'referenceSeriesUID',35 'label',36 'description',37 'type',38 'unit',39 'area', // TODO: Add concept names instead (descriptor)40 'mean',41 'stdDev',42 'length',43 'shortestDiameter',44 'longestDiameter',45 'text', // NOTE: There is nothing like this in SR.46 'points',47 'source',48];49const EVENTS = {50 MEASUREMENT_UPDATED: 'event::measurement_updated',51 INTERNAL_MEASUREMENT_UPDATED: 'event:internal_measurement_updated',52 MEASUREMENT_ADDED: 'event::measurement_added',53 MEASUREMENT_REMOVED: 'event::measurement_removed',54 MEASUREMENTS_CLEARED: 'event::measurements_cleared',55 JUMP_TO_MEASUREMENT: 'event:jump_to_measurement',56};57const VALUE_TYPES = {58 POLYLINE: 'value_type::polyline',59 POINT: 'value_type::point',60 BIDIRECTIONAL: 'value_type::shortAxisLongAxis', // TODO -> Discuss with Danny. => just using SCOORD values isn't enough here.61 ELLIPSE: 'value_type::ellipse',62 MULTIPOINT: 'value_type::multipoint',63 CIRCLE: 'value_type::circle',64};65class MeasurementService {66 constructor() {67 this.sources = {};68 this.mappings = {};69 this.measurements = {};70 this.listeners = {};71 this._jumpToMeasurementCache = {};72 Object.defineProperty(this, 'EVENTS', {73 value: EVENTS,74 writable: false,75 enumerable: true,76 configurable: false,77 });78 Object.defineProperty(this, 'VALUE_TYPES', {79 value: VALUE_TYPES,80 writable: false,81 enumerable: true,82 configurable: false,83 });84 Object.assign(this, pubSubServiceInterface);85 }86 /**87 * Get all measurements.88 *89 * @return {Measurement[]} Array of measurements90 */91 getMeasurements() {92 const measurements = this._arrayOfObjects(this.measurements);93 return (94 measurements &&95 measurements.map(m => this.measurements[Object.keys(m)[0]])96 );97 }98 /**99 * Get specific measurement by its id.100 *101 * @param {string} id If of the measurement102 * @return {Measurement} Measurement instance103 */104 getMeasurement(id) {105 let measurement = null;106 const measurements = this.measurements[id];107 if (measurements && Object.keys(measurements).length > 0) {108 measurement = this.measurements[id];109 }110 return measurement;111 }112 /**113 * Create a new source.114 *115 * @param {string} name Name of the source116 * @param {string} version Source name117 * @return {MeasurementSource} Measurement source instance118 */119 createSource(name, version) {120 if (!name) {121 throw new Error('Source name not provided.');122 }123 if (!version) {124 throw new Error('Source version not provided.');125 }126 const id = guid();127 const source = {128 id,129 name,130 version,131 };132 source.addOrUpdate = (definition, measurement) => {133 return this.addOrUpdate(source, definition, measurement);134 };135 source.remove = id => {136 return this.remove(id, source);137 };138 source.getAnnotation = (definition, measurementId) => {139 return this.getAnnotation(source, definition, measurementId);140 };141 log.info(`New '${name}@${version}' source added.`);142 this.sources[id] = source;143 return source;144 }145 getSource(name, version) {146 const { sources } = this;147 const id = this._getSourceId(name, version);148 return sources[id];149 }150 getSourceMappings(name, version) {151 const { mappings } = this;152 const id = this._getSourceId(name, version);153 return mappings[id];154 }155 _getSourceId(name, version) {156 const { sources } = this;157 const sourceId = Object.keys(sources).find(sourceId => {158 const source = sources[sourceId];159 return source.name === name && source.version === version;160 });161 return sourceId;162 }163 /**164 * Add a new measurement matching criteria along with mapping functions.165 *166 * @param {MeasurementSource} source Measurement source instance167 * @param {string} definition Definition of the measurement (Annotation Type)168 * @param {MatchingCriteria} matchingCriteria The matching criteria169 * @param {Function} toSourceSchema Mapping function to source schema170 * @param {Function} toMeasurementSchema Mapping function to measurement schema171 * @return void172 */173 addMapping(174 source,175 definition,176 matchingCriteria,177 toSourceSchema,178 toMeasurementSchema179 ) {180 if (!this._isValidSource(source)) {181 throw new Error('Invalid source.');182 }183 if (!matchingCriteria) {184 throw new Error('Matching criteria not provided.');185 }186 if (!definition) {187 throw new Error('Definition not provided.');188 }189 if (!toSourceSchema) {190 throw new Error('Mapping function to source schema not provided.');191 }192 if (!toMeasurementSchema) {193 throw new Error('Measurement mapping function not provided.');194 }195 const mapping = {196 matchingCriteria,197 definition,198 toSourceSchema,199 toMeasurementSchema,200 };201 if (Array.isArray(this.mappings[source.id])) {202 this.mappings[source.id].push(mapping);203 } else {204 this.mappings[source.id] = [mapping];205 }206 log.info(207 `New measurement mapping added to source '${this._getSourceInfo(208 source209 )}'.`210 );211 }212 /**213 * Get annotation for specific source.214 *215 * @param {MeasurementSource} source Measurement source instance216 * @param {string} definition The source definition217 * @param {string} measurementId The measurement service measurement id218 * @return {Object} Source measurement schema219 */220 getAnnotation(source, definition, measurementId) {221 if (!this._isValidSource(source)) {222 log.warn('Invalid source. Exiting early.');223 return;224 }225 if (!definition) {226 log.warn('No source definition provided. Exiting early.');227 return;228 }229 const mapping = this._getMappingByMeasurementSource(230 measurementId,231 definition232 );233 const measurement = this.getMeasurement(measurementId);234 if (mapping) return mapping.toSourceSchema(measurement, definition);235 const matchingMapping = this._getMatchingMapping(236 source,237 definition,238 measurement239 );240 if (matchingMapping) {241 log.info('Matching mapping found:', matchingMapping);242 const { toSourceSchema, definition } = matchingMapping;243 return toSourceSchema(measurement, definition);244 }245 }246 update(id, measurement, notYetUpdatedAtSource = false) {247 if (this.measurements[id]) {248 const updatedMeasurement = {249 ...measurement,250 modifiedTimestamp: Math.floor(Date.now() / 1000),251 };252 log.info(253 `Updating internal measurement representation...`,254 updatedMeasurement255 );256 this.measurements[id] = updatedMeasurement;257 this._broadcastEvent(258 // Add an internal flag to say the measurement has not yet been updated at source.259 this.EVENTS.MEASUREMENT_UPDATED,260 {261 source: measurement.source,262 measurement: updatedMeasurement,263 notYetUpdatedAtSource,264 }265 );266 return updatedMeasurement.id;267 }268 }269 /**270 * Add a raw measurement into a source so that it may be271 * Converted to/from annotation in the same way. E.g. import serialized data272 * Of the same form as the measurement source.273 * @param {MeasurementSource} source The measurement source instance.274 * @param {string} definition The source definition you want to add the measuremnet to.275 * @param {object} data The data you wish to add to the source.276 * @param {function} toMeasurementSchema A function to get the `data` into the same shape as the source definition.277 */278 addRawMeasurement(source, definition, data, toMeasurementSchema) {279 if (!this._isValidSource(source)) {280 log.warn('Invalid source. Exiting early.');281 return;282 }283 const sourceInfo = this._getSourceInfo(source);284 if (!definition) {285 log.warn('No source definition provided. Exiting early.');286 return;287 }288 if (!this._sourceHasMappings(source)) {289 log.warn(290 `No measurement mappings found for '${sourceInfo}' source. Exiting early.`291 );292 return;293 }294 let measurement = {};295 try {296 /* Convert measurement */297 measurement = toMeasurementSchema(data);298 /* Assign measurement source instance */299 measurement.source = source;300 } catch (error) {301 log.warn(302 `Failed to map '${sourceInfo}' measurement for definition ${definition}:`,303 error.message304 );305 return;306 }307 if (!this._isValidMeasurement(measurement)) {308 log.warn(309 `Attempting to add or update a invalid measurement provided by '${sourceInfo}'. Exiting early.`310 );311 return;312 }313 let internalId = data.id;314 if (!internalId) {315 internalId = guid();316 log.warn(`Measurement ID not found. Generating UID: ${internalId}`);317 }318 const newMeasurement = {319 ...measurement,320 modifiedTimestamp: Math.floor(Date.now() / 1000),321 id: internalId,322 };323 if (this.measurements[internalId]) {324 log.info(325 `Measurement already defined. Updating measurement.`,326 newMeasurement327 );328 this.measurements[internalId] = newMeasurement;329 this._broadcastEvent(this.EVENTS.MEASUREMENT_UPDATED, {330 source,331 measurement: newMeasurement,332 });333 } else {334 log.info(`Measurement added.`, newMeasurement);335 this.measurements[internalId] = newMeasurement;336 this._broadcastEvent(this.EVENTS.MEASUREMENT_ADDED, {337 source,338 measurement: newMeasurement,339 });340 }341 return newMeasurement.id;342 }343 /**344 * Adds or update persisted measurements.345 *346 * @param {MeasurementSource} source The measurement source instance347 * @param {string} definition The source definition348 * @param {Measurement} measurement The source measurement349 * @return {string} A measurement id350 */351 addOrUpdate(source, definition, sourceMeasurement) {352 if (!this._isValidSource(source)) {353 throw new Error('Invalid source.');354 }355 if (!definition) {356 throw new Error('No source definition provided.');357 }358 const sourceInfo = this._getSourceInfo(source);359 if (!this._sourceHasMappings(source)) {360 throw new Error(361 `No measurement mappings found for '${sourceInfo}' source. Exiting early.`362 );363 }364 let measurement = {};365 try {366 const sourceMappings = this.mappings[source.id];367 const { toMeasurementSchema } = sourceMappings.find(368 mapping => mapping.definition === definition369 );370 /* Convert measurement */371 measurement = toMeasurementSchema(sourceMeasurement);372 /* Assign measurement source instance */373 measurement.source = source;374 } catch (error) {375 throw new Error(376 `Failed to map '${sourceInfo}' measurement for definition ${definition}:`,377 error.message378 );379 }380 if (!this._isValidMeasurement(measurement)) {381 throw new Error(382 `Attempting to add or update a invalid measurement provided by '${sourceInfo}'. Exiting early.`383 );384 }385 let internalId = sourceMeasurement.id;386 if (!internalId) {387 internalId = guid();388 log.info(`Measurement ID not found. Generating UID: ${internalId}`);389 }390 const newMeasurement = {391 ...measurement,392 modifiedTimestamp: Math.floor(Date.now() / 1000),393 id: internalId,394 };395 if (this.measurements[internalId]) {396 log.info(397 `Measurement already defined. Updating measurement.`,398 newMeasurement399 );400 this.measurements[internalId] = newMeasurement;401 this._broadcastEvent(this.EVENTS.MEASUREMENT_UPDATED, {402 source,403 measurement: newMeasurement,404 notYetUpdatedAtSource: false,405 });406 } else {407 log.info('Measurement added.', newMeasurement);408 this.measurements[internalId] = newMeasurement;409 this._broadcastEvent(this.EVENTS.MEASUREMENT_ADDED, {410 source,411 measurement: newMeasurement,412 });413 }414 return newMeasurement.id;415 }416 /**417 * Removes a measurement and broadcasts the removed event.418 *419 * @param {string} id The measurement id420 * @param {MeasurementSource} source The measurement source instance421 * @return {string} The removed measurement id422 */423 remove(id, source) {424 if (!id || !this.measurements[id]) {425 log.warn(`No id provided, or unable to find measurement by id.`);426 return;427 }428 delete this.measurements[id];429 this._broadcastEvent(this.EVENTS.MEASUREMENT_REMOVED, {430 source,431 measurement: id, // This is weird :shrug:432 });433 }434 clearMeasurements() {435 this.measurements = {};436 this._broadcastEvent(this.EVENTS.MEASUREMENTS_CLEARED);437 }438 jumpToMeasurement(viewportIndex, id) {439 const measurement = this.measurements[id];440 if (!measurement) {441 log.warn(`No id provided, or unable to find measurement by id.`);442 return;443 }444 this._addJumpToMeasurement(viewportIndex, id);445 const eventName = this.EVENTS.JUMP_TO_MEASUREMENT;446 const hasListeners = Object.keys(this.listeners).length > 0;447 const hasCallbacks = Array.isArray(this.listeners[eventName]);448 if (hasListeners && hasCallbacks) {449 this.listeners[eventName].forEach(listener => {450 listener.callback({ viewportIndex, measurement });451 });452 }453 }454 _addJumpToMeasurement(viewportIndex, id) {455 this._jumpToMeasurementCache[viewportIndex] = id;456 }457 getJumpToMeasurement(viewportIndex) {458 return this._jumpToMeasurementCache[viewportIndex];459 }460 removeJumpToMeasurement(viewportIndex) {461 delete this._jumpToMeasurementCache[viewportIndex];462 }463 _getMappingByMeasurementSource(measurementId, definition) {464 const measurement = this.getMeasurement(measurementId);465 if (this._isValidSource(measurement.source)) {466 return this.mappings[measurement.source.id].find(467 m => m.definition === definition468 );469 }470 }471 /**472 * Clear all measurements and broadcasts cleared event.473 */474 clear() {475 this.measurements = {};476 this._broadcastEvent(this.EVENTS.MEASUREMENTS_CLEARED);477 }478 /**479 * Get measurement mapping function if matching criteria.480 *481 * @param {MeasurementSource} source Measurement source instance482 * @param {string} definition The source definition483 * @param {Measurement} measurement The measurement service measurement484 * @return {Object} The mapping based on matched criteria485 */486 _getMatchingMapping(source, definition, measurement) {487 const sourceMappings = this.mappings[source.id];488 const sourceMappingsByDefinition = sourceMappings.filter(489 mapping => mapping.definition === definition490 );491 /* Criteria Matching */492 return sourceMappingsByDefinition.find(({ matchingCriteria }) => {493 return (494 measurement.points &&495 measurement.points.length === matchingCriteria.points496 );497 });498 }499 /**500 * Returns formatted string with source info.501 *502 * @param {MeasurementSource} source Measurement source503 * @return {string} Source information504 */505 _getSourceInfo(source) {506 return `${source.name}@${source.version}`;507 }508 /**509 * Checks if given source is valid.510 *511 * @param {MeasurementSource} source Measurement source512 * @return {boolean} Measurement source validation513 */514 _isValidSource(source) {515 return source && this.sources[source.id];516 }517 /**518 * Checks if a given source has mappings.519 *520 * @param {MeasurementSource} source The measurement source521 * @return {boolean} Validation if source has mappings522 */523 _sourceHasMappings(source) {524 return (525 Array.isArray(this.mappings[source.id]) && this.mappings[source.id].length526 );527 }528 /**529 * Check if a given measurement data is valid.530 *531 * @param {Measurement} measurementData Measurement data532 * @return {boolean} Measurement validation533 */534 _isValidMeasurement(measurementData) {535 Object.keys(measurementData).forEach(key => {536 if (!MEASUREMENT_SCHEMA_KEYS.includes(key)) {537 log.warn(`Invalid measurement key: ${key}`);538 return false;539 }540 });541 return true;542 }543 /**544 * Check if a given measurement service event is valid.545 *546 * @param {string} eventName The name of the event547 * @return {boolean} Event name validation548 // */549 // _isValidEvent(eventName) {550 // return Object.values(this.EVENTS).includes(eventName);551 // }552 /**553 * Converts object of objects to array.554 *555 * @return {Array} Array of objects556 */557 _arrayOfObjects = obj => {558 return Object.entries(obj).map(e => ({ [e[0]]: e[1] }));559 };560}561export default MeasurementService;...
s2sTesting_spec.js
Source:s2sTesting_spec.js
1import s2sTesting from 'modules/s2sTesting';2import { config } from 'src/config';3import find from 'core-js/library/fn/array/find';4var events = require('src/events');5var CONSTANTS = require('src/constants.json');6const BID_ADJUSTMENT = CONSTANTS.EVENTS.BID_ADJUSTMENT;7var expect = require('chai').expect;8describe('s2sTesting', function () {9 let mathRandomStub;10 let randomNumber = 0;11 beforeEach(function () {12 mathRandomStub = sinon.stub(Math, 'random').callsFake(() => { return randomNumber; });13 });14 afterEach(function () {15 mathRandomStub.restore();16 });17 describe('s2sTesting.getSource', function () {18 // helper function to set random number and get the source19 function getExpectedSource(randNumber, sourceWeights, sources) {20 // set random number for testing21 randomNumber = randNumber;22 return s2sTesting.getSource(sourceWeights, sources);23 }24 it('returns undefined if no sources', function () {25 expect(getExpectedSource(0, {})).to.be.undefined;26 expect(getExpectedSource(0.5, {})).to.be.undefined;27 expect(getExpectedSource(0.9999, {})).to.be.undefined;28 });29 it('returns undefined if no weights', function () {30 expect(getExpectedSource(0, {server: 0, client: 0})).to.be.undefined;31 expect(getExpectedSource(0.5, {client: 0})).to.be.undefined;32 });33 it('gets the expected source from 3 sources', function () {34 var sources = ['server', 'client', 'both'];35 expect(getExpectedSource(0, {server: 1, client: 1, both: 2}, sources)).to.equal('server');36 expect(getExpectedSource(0.2499999, {server: 1, client: 1, both: 2}, sources)).to.equal('server');37 expect(getExpectedSource(0.25, {server: 1, client: 1, both: 2}, sources)).to.equal('client');38 expect(getExpectedSource(0.49999, {server: 1, client: 1, both: 2}, sources)).to.equal('client');39 expect(getExpectedSource(0.5, {server: 1, client: 1, both: 2}, sources)).to.equal('both');40 expect(getExpectedSource(0.99999, {server: 1, client: 1, both: 2}, sources)).to.equal('both');41 });42 it('gets the expected source from 2 sources', function () {43 expect(getExpectedSource(0, {server: 2, client: 3})).to.equal('server');44 expect(getExpectedSource(0.39999, {server: 2, client: 3})).to.equal('server');45 expect(getExpectedSource(0.4, {server: 2, client: 3})).to.equal('client');46 expect(getExpectedSource(0.9, {server: 2, client: 3})).to.equal('client');47 var sources = ['server', 'client', 'both'];48 expect(getExpectedSource(0, {server: 2, client: 3}, sources)).to.equal('server');49 expect(getExpectedSource(0.39999, {server: 2, client: 3}, sources)).to.equal('server');50 expect(getExpectedSource(0.4, {server: 2, client: 3}, sources)).to.equal('client');51 expect(getExpectedSource(0.9, {server: 2, client: 3}, sources)).to.equal('client');52 });53 it('gets the expected source from 1 source', function () {54 expect(getExpectedSource(0, {client: 2})).to.equal('client');55 expect(getExpectedSource(0.5, {client: 2})).to.equal('client');56 expect(getExpectedSource(0.99999, {client: 2})).to.equal('client');57 });58 it('ignores an invalid source', function () {59 expect(getExpectedSource(0, {client: 2, cache: 2})).to.equal('client');60 expect(getExpectedSource(0.3333, {server: 1, cache: 1, client: 2})).to.equal('server');61 expect(getExpectedSource(0.34, {server: 1, cache: 1, client: 2})).to.equal('client');62 });63 it('ignores order of sources', function () {64 var sources = ['server', 'client', 'both'];65 expect(getExpectedSource(0, {client: 1, server: 1, both: 2}, sources)).to.equal('server');66 expect(getExpectedSource(0.2499999, {both: 2, client: 1, server: 1}, sources)).to.equal('server');67 expect(getExpectedSource(0.25, {client: 1, both: 2, server: 1}, sources)).to.equal('client');68 expect(getExpectedSource(0.49999, {server: 1, both: 2, client: 1}, sources)).to.equal('client');69 expect(getExpectedSource(0.5, {both: 2, server: 1, client: 1}, sources)).to.equal('both');70 });71 it('accepts an array of sources', function () {72 expect(getExpectedSource(0.3333, {second: 2, first: 1}, ['first', 'second'])).to.equal('first');73 expect(getExpectedSource(0.34, {second: 2, first: 1}, ['first', 'second'])).to.equal('second');74 expect(getExpectedSource(0.9999, {second: 2, first: 1}, ['first', 'second'])).to.equal('second');75 });76 });77 describe('s2sTesting.getSourceBidderMap', function () {78 describe('setting source through s2sConfig', function () {79 beforeEach(function () {80 // set random number for testing81 randomNumber = 0.7;82 });83 it('does not work if testing is "false"', function () {84 config.setConfig({s2sConfig: {85 bidders: ['rubicon'],86 testing: false,87 bidderControl: {rubicon: {bidSource: {server: 1, client: 1}}}88 }});89 expect(s2sTesting.getSourceBidderMap()).to.eql({90 server: [],91 client: []92 });93 });94 it('sets one client bidder', function () {95 config.setConfig({s2sConfig: {96 bidders: ['rubicon'],97 testing: true,98 bidderControl: {rubicon: {bidSource: {server: 1, client: 1}}}99 }});100 expect(s2sTesting.getSourceBidderMap()).to.eql({101 server: [],102 client: ['rubicon']103 });104 });105 it('sets one server bidder', function () {106 config.setConfig({s2sConfig: {107 bidders: ['rubicon'],108 testing: true,109 bidderControl: {rubicon: {bidSource: {server: 4, client: 1}}}110 }});111 expect(s2sTesting.getSourceBidderMap()).to.eql({112 server: ['rubicon'],113 client: []114 });115 });116 it('defaults to server', function () {117 config.setConfig({s2sConfig: {118 bidders: ['rubicon'],119 testing: true120 }});121 expect(s2sTesting.getSourceBidderMap()).to.eql({122 server: ['rubicon'],123 client: []124 });125 });126 it('sets two bidders', function () {127 config.setConfig({s2sConfig: {128 bidders: ['rubicon', 'appnexus'],129 testing: true,130 bidderControl: {131 rubicon: {bidSource: {server: 3, client: 1}},132 appnexus: {bidSource: {server: 1, client: 1}}133 }}});134 var serverClientBidders = s2sTesting.getSourceBidderMap();135 expect(serverClientBidders.server).to.eql(['rubicon']);136 expect(serverClientBidders.client).to.have.members(['appnexus']);137 });138 });139 describe('setting source through adUnits', function () {140 beforeEach(function () {141 // reset s2sconfig bid sources142 config.setConfig({s2sConfig: {testing: true}});143 // set random number for testing144 randomNumber = 0.7;145 });146 it('sets one bidder source from one adUnit', function () {147 var adUnits = [148 {bids: [149 {bidder: 'rubicon', bidSource: {server: 4, client: 1}}150 ]}151 ];152 expect(s2sTesting.getSourceBidderMap(adUnits)).to.eql({153 server: ['rubicon'],154 client: []155 });156 // should have saved the source on the bid157 expect(adUnits[0].bids[0].calcSource).to.equal('server');158 expect(adUnits[0].bids[0].finalSource).to.equal('server');159 adUnits = [160 {bids: [161 {bidder: 'rubicon', bidSource: {server: 1, client: 1}}162 ]}163 ];164 expect(s2sTesting.getSourceBidderMap(adUnits)).to.eql({165 server: [],166 client: ['rubicon']167 });168 // should have saved the source on the bid169 expect(adUnits[0].bids[0].calcSource).to.equal('client');170 expect(adUnits[0].bids[0].finalSource).to.equal('client');171 });172 it('defaults to client if no bidSource', function () {173 var adUnits = [174 {bids: [175 {bidder: 'rubicon', bidSource: {}}176 ]}177 ];178 expect(s2sTesting.getSourceBidderMap(adUnits)).to.eql({179 server: [],180 client: ['rubicon']181 });182 // should have saved the source on the bid183 expect(adUnits[0].bids[0].calcSource).to.be.undefined;184 expect(adUnits[0].bids[0].finalSource).to.equal('client');185 });186 it('sets multiple bidders sources from one adUnit', function () {187 var adUnits = [188 {bids: [189 {bidder: 'rubicon', bidSource: {server: 2, client: 1}},190 {bidder: 'appnexus', bidSource: {server: 3, client: 1}}191 ]}192 ];193 var serverClientBidders = s2sTesting.getSourceBidderMap(adUnits);194 expect(serverClientBidders.server).to.eql(['appnexus']);195 expect(serverClientBidders.client).to.have.members(['rubicon']);196 // should have saved the source on the bid197 expect(adUnits[0].bids[0].calcSource).to.equal('client');198 expect(adUnits[0].bids[0].finalSource).to.equal('client');199 expect(adUnits[0].bids[1].calcSource).to.equal('server');200 expect(adUnits[0].bids[1].finalSource).to.equal('server');201 });202 it('sets multiple bidders sources from multiple adUnits', function () {203 var adUnits = [204 {bids: [205 {bidder: 'rubicon', bidSource: {server: 2, client: 1}},206 {bidder: 'appnexus', bidSource: {server: 1, client: 1}}207 ]},208 {bids: [209 {bidder: 'rubicon', bidSource: {server: 4, client: 1}},210 {bidder: 'bidder3', bidSource: {client: 1}}211 ]}212 ];213 var serverClientBidders = s2sTesting.getSourceBidderMap(adUnits);214 expect(serverClientBidders.server).to.have.members(['rubicon']);215 expect(serverClientBidders.server).to.not.have.members(['appnexus', 'bidder3']);216 expect(serverClientBidders.client).to.have.members(['rubicon', 'appnexus', 'bidder3']);217 // should have saved the source on the bid218 expect(adUnits[0].bids[0].calcSource).to.equal('client');219 expect(adUnits[0].bids[0].finalSource).to.equal('client');220 expect(adUnits[0].bids[1].calcSource).to.equal('client');221 expect(adUnits[0].bids[1].finalSource).to.equal('client');222 expect(adUnits[1].bids[0].calcSource).to.equal('server');223 expect(adUnits[1].bids[0].finalSource).to.equal('server');224 expect(adUnits[1].bids[1].calcSource).to.equal('client');225 expect(adUnits[1].bids[1].finalSource).to.equal('client');226 });227 it('should reuse calculated sources', function () {228 var adUnits = [229 {bids: [230 {bidder: 'rubicon', calcSource: 'client', bidSource: {server: 4, client: 1}},231 {bidder: 'appnexus', calcSource: 'server', bidSource: {server: 1, client: 1}},232 {bidder: 'bidder3', calcSource: 'server', bidSource: {client: 1}}233 ]}234 ];235 var serverClientBidders = s2sTesting.getSourceBidderMap(adUnits);236 expect(serverClientBidders.server).to.have.members(['appnexus', 'bidder3']);237 expect(serverClientBidders.server).to.not.have.members(['rubicon']);238 expect(serverClientBidders.client).to.have.members(['rubicon']);239 expect(serverClientBidders.client).to.not.have.members(['appnexus', 'bidder3']);240 // should have saved the source on the bid241 expect(adUnits[0].bids[0].calcSource).to.equal('client');242 expect(adUnits[0].bids[0].finalSource).to.equal('client');243 expect(adUnits[0].bids[1].calcSource).to.equal('server');244 expect(adUnits[0].bids[1].finalSource).to.equal('server');245 expect(adUnits[0].bids[2].calcSource).to.equal('server');246 expect(adUnits[0].bids[2].finalSource).to.equal('server');247 });248 });249 describe('setting source through s2sconfig and adUnits', function () {250 beforeEach(function () {251 // reset s2sconfig bid sources252 config.setConfig({s2sConfig: {testing: true}});253 // set random number for testing254 randomNumber = 0.7;255 });256 it('should get sources from both', function () {257 // set rubicon: server and appnexus: client258 var adUnits = [259 {bids: [260 {bidder: 'rubicon', bidSource: {server: 4, client: 1}},261 {bidder: 'appnexus', bidSource: {client: 1}}262 ]}263 ];264 // set rubicon: client and appnexus: server265 config.setConfig({s2sConfig: {266 bidders: ['rubicon', 'appnexus'],267 testing: true,268 bidderControl: {269 rubicon: {bidSource: {server: 2, client: 1}},270 appnexus: {bidSource: {server: 1}}271 }272 }});273 var serverClientBidders = s2sTesting.getSourceBidderMap(adUnits);274 expect(serverClientBidders.server).to.have.members(['rubicon', 'appnexus']);275 expect(serverClientBidders.client).to.have.members(['rubicon', 'appnexus']);276 });277 });278 });...
InventorySourceForm.jsx
Source:InventorySourceForm.jsx
1import React, { useEffect, useCallback, useContext } from 'react';2import { Formik, useField, useFormikContext } from 'formik';3import { func, shape } from 'prop-types';4import { withI18n } from '@lingui/react';5import { t } from '@lingui/macro';6import { Form, FormGroup, Title } from '@patternfly/react-core';7import { InventorySourcesAPI } from '../../../api';8import { ConfigContext } from '../../../contexts/Config';9import useRequest from '../../../util/useRequest';10import { required } from '../../../util/validators';11import AnsibleSelect from '../../../components/AnsibleSelect';12import ContentError from '../../../components/ContentError';13import ContentLoading from '../../../components/ContentLoading';14import FormActionGroup from '../../../components/FormActionGroup/FormActionGroup';15import FormField, { FormSubmitError } from '../../../components/FormField';16import {17 FormColumnLayout,18 SubFormLayout,19} from '../../../components/FormLayout';20import Popover from '../../../components/Popover';21import {22 AzureSubForm,23 EC2SubForm,24 GCESubForm,25 OpenStackSubForm,26 SCMSubForm,27 SatelliteSubForm,28 TowerSubForm,29 VMwareSubForm,30 VirtualizationSubForm,31} from './InventorySourceSubForms';32const buildSourceChoiceOptions = options => {33 const sourceChoices = options.actions.GET.source.choices.map(34 ([choice, label]) => ({ label, key: choice, value: choice })35 );36 return sourceChoices.filter(({ key }) => key !== 'file');37};38const InventorySourceFormFields = ({ source, sourceOptions, i18n }) => {39 const {40 values,41 initialValues,42 resetForm,43 setFieldTouched,44 setFieldValue,45 } = useFormikContext();46 const [sourceField, sourceMeta] = useField({47 name: 'source',48 validate: required(i18n._(t`Set a value for this field`), i18n),49 });50 const { custom_virtualenvs } = useContext(ConfigContext);51 const [venvField] = useField('custom_virtualenv');52 const defaultVenv = {53 label: i18n._(t`Use Default Ansible Environment`),54 value: '/var/lib/awx/venv/ansible/',55 key: 'default',56 };57 const resetSubFormFields = sourceType => {58 if (sourceType === initialValues.source) {59 resetForm({60 values: {61 ...initialValues,62 name: values.name,63 description: values.description,64 custom_virtualenv: values.custom_virtualenv,65 source: sourceType,66 },67 });68 } else {69 const defaults = {70 credential: null,71 overwrite: false,72 overwrite_vars: false,73 source: sourceType,74 source_path: '',75 source_project: null,76 source_script: null,77 source_vars: '---\n',78 update_cache_timeout: 0,79 update_on_launch: false,80 update_on_project_update: false,81 verbosity: 1,82 enabled_var: '',83 enabled_value: '',84 host_filter: '',85 };86 Object.keys(defaults).forEach(label => {87 setFieldValue(label, defaults[label]);88 setFieldTouched(label, false);89 });90 }91 };92 return (93 <>94 <FormField95 id="name"96 label={i18n._(t`Name`)}97 name="name"98 type="text"99 validate={required(null, i18n)}100 isRequired101 />102 <FormField103 id="description"104 label={i18n._(t`Description`)}105 name="description"106 type="text"107 />108 <FormGroup109 fieldId="source"110 helperTextInvalid={sourceMeta.error}111 isRequired112 validated={113 !sourceMeta.touched || !sourceMeta.error ? 'default' : 'error'114 }115 label={i18n._(t`Source`)}116 >117 <AnsibleSelect118 {...sourceField}119 id="source"120 data={[121 {122 value: '',123 key: '',124 label: i18n._(t`Choose a source`),125 isDisabled: true,126 },127 ...buildSourceChoiceOptions(sourceOptions),128 ]}129 onChange={(event, value) => {130 resetSubFormFields(value);131 }}132 />133 </FormGroup>134 {custom_virtualenvs && custom_virtualenvs.length > 1 && (135 <FormGroup136 fieldId="custom-virtualenv"137 label={i18n._(t`Ansible Environment`)}138 labelIcon={139 <Popover140 content={i18n._(t`Select the custom141 Python virtual environment for this142 inventory source sync to run on.`)}143 />144 }145 >146 <AnsibleSelect147 id="custom-virtualenv"148 data={[149 defaultVenv,150 ...custom_virtualenvs151 .filter(value => value !== defaultVenv.value)152 .map(value => ({ value, label: value, key: value })),153 ]}154 {...venvField}155 />156 </FormGroup>157 )}158 {sourceField.value !== '' && (159 <SubFormLayout>160 <Title size="md" headingLevel="h4">161 {i18n._(t`Source details`)}162 </Title>163 <FormColumnLayout>164 {165 {166 azure_rm: (167 <AzureSubForm168 autoPopulateCredential={169 !source?.id || source?.source !== 'azure_rm'170 }171 sourceOptions={sourceOptions}172 />173 ),174 ec2: <EC2SubForm sourceOptions={sourceOptions} />,175 gce: (176 <GCESubForm177 autoPopulateCredential={178 !source?.id || source?.source !== 'gce'179 }180 sourceOptions={sourceOptions}181 />182 ),183 openstack: (184 <OpenStackSubForm185 autoPopulateCredential={186 !source?.id || source?.source !== 'openstack'187 }188 />189 ),190 rhv: (191 <VirtualizationSubForm192 autoPopulateCredential={193 !source?.id || source?.source !== 'rhv'194 }195 />196 ),197 satellite6: (198 <SatelliteSubForm199 autoPopulateCredential={200 !source?.id || source?.source !== 'satellite6'201 }202 />203 ),204 scm: (205 <SCMSubForm206 autoPopulateProject={207 !source?.id || source?.source !== 'scm'208 }209 />210 ),211 tower: (212 <TowerSubForm213 autoPopulateCredential={214 !source?.id || source?.source !== 'tower'215 }216 />217 ),218 vmware: (219 <VMwareSubForm220 autoPopulateCredential={221 !source?.id || source?.source !== 'vmware'222 }223 sourceOptions={sourceOptions}224 />225 ),226 }[sourceField.value]227 }228 </FormColumnLayout>229 </SubFormLayout>230 )}231 </>232 );233};234const InventorySourceForm = ({235 i18n,236 onCancel,237 onSubmit,238 source,239 submitError = null,240}) => {241 const initialValues = {242 credential: source?.summary_fields?.credential || null,243 custom_virtualenv: source?.custom_virtualenv || '',244 description: source?.description || '',245 name: source?.name || '',246 overwrite: source?.overwrite || false,247 overwrite_vars: source?.overwrite_vars || false,248 source: source?.source || '',249 source_path: source?.source_path || '',250 source_project: source?.summary_fields?.source_project || null,251 source_script: source?.summary_fields?.source_script || null,252 source_vars: source?.source_vars || '---\n',253 update_cache_timeout: source?.update_cache_timeout || 0,254 update_on_launch: source?.update_on_launch || false,255 update_on_project_update: source?.update_on_project_update || false,256 verbosity: source?.verbosity || 1,257 enabled_var: source?.enabled_var || '',258 enabled_value: source?.enabled_value || '',259 host_filter: source?.host_filter || '',260 };261 const {262 isLoading: isSourceOptionsLoading,263 error: sourceOptionsError,264 request: fetchSourceOptions,265 result: sourceOptions,266 } = useRequest(267 useCallback(async () => {268 const { data } = await InventorySourcesAPI.readOptions();269 return data;270 }, []),271 null272 );273 useEffect(() => {274 fetchSourceOptions();275 }, [fetchSourceOptions]);276 if (sourceOptionsError) {277 return <ContentError error={sourceOptionsError} />;278 }279 if (!sourceOptions || isSourceOptionsLoading) {280 return <ContentLoading />;281 }282 return (283 <Formik284 initialValues={initialValues}285 onSubmit={values => {286 onSubmit(values);287 }}288 >289 {formik => (290 <Form autoComplete="off" onSubmit={formik.handleSubmit}>291 <FormColumnLayout>292 <InventorySourceFormFields293 formik={formik}294 i18n={i18n}295 source={source}296 sourceOptions={sourceOptions}297 />298 {submitError && <FormSubmitError error={submitError} />}299 <FormActionGroup300 onCancel={onCancel}301 onSubmit={formik.handleSubmit}302 />303 </FormColumnLayout>304 </Form>305 )}306 </Formik>307 );308};309InventorySourceForm.propTypes = {310 onCancel: func.isRequired,311 onSubmit: func.isRequired,312 submitError: shape({}),313};314InventorySourceForm.defaultProps = {315 submitError: null,316};...
Bundle-test.js
Source:Bundle-test.js
1/**2 * Copyright (c) 2015-present, Facebook, Inc.3 * All rights reserved.4 *5 * This source code is licensed under the BSD-style license found in the6 * LICENSE file in the root directory of this source tree. An additional grant7 * of patent rights can be found in the PATENTS file in the same directory.8 */9'use strict';10jest.autoMockOff();11var SourceMapGenerator = require('source-map').SourceMapGenerator;12var Bundle = require('../Bundle');13var ModuleTransport = require('../../lib/ModuleTransport');14var UglifyJS = require('uglify-js');15describe('Bundle', function() {16 var bundle;17 beforeEach(function() {18 bundle = new Bundle('test_url');19 bundle.getSourceMap = jest.genMockFn().mockImpl(function() {20 return 'test-source-map';21 });22 });23 describe('source bundle', function() {24 it('should create a bundle and get the source', function() {25 bundle.addModule(new ModuleTransport({26 code: 'transformed foo;',27 sourceCode: 'source foo',28 sourcePath: 'foo path',29 }));30 bundle.addModule(new ModuleTransport({31 code: 'transformed bar;',32 sourceCode: 'source bar',33 sourcePath: 'bar path',34 }));35 bundle.finalize({});36 expect(bundle.getSource({dev: true})).toBe([37 'transformed foo;',38 'transformed bar;',39 '\/\/@ sourceMappingURL=test_url'40 ].join('\n'));41 });42 it('should be ok to leave out the source map url', function() {43 var p = new Bundle();44 p.addModule(new ModuleTransport({45 code: 'transformed foo;',46 sourceCode: 'source foo',47 sourcePath: 'foo path',48 }));49 p.addModule(new ModuleTransport({50 code: 'transformed bar;',51 sourceCode: 'source bar',52 sourcePath: 'bar path',53 }));54 p.finalize({});55 expect(p.getSource({dev: true})).toBe([56 'transformed foo;',57 'transformed bar;',58 ].join('\n'));59 });60 it('should create a bundle and add run module code', function() {61 bundle.addModule(new ModuleTransport({62 code: 'transformed foo;',63 sourceCode: 'source foo',64 sourcePath: 'foo path'65 }));66 bundle.addModule(new ModuleTransport({67 code: 'transformed bar;',68 sourceCode: 'source bar',69 sourcePath: 'bar path'70 }));71 bundle.setMainModuleId('foo');72 bundle.finalize({73 runBeforeMainModule: ['bar'],74 runMainModule: true,75 });76 expect(bundle.getSource({dev: true})).toBe([77 'transformed foo;',78 'transformed bar;',79 ';require("bar");',80 ';require("foo");',81 '\/\/@ sourceMappingURL=test_url',82 ].join('\n'));83 });84 it('should get minified source', function() {85 var minified = {86 code: 'minified',87 map: 'map',88 };89 UglifyJS.minify = function() {90 return minified;91 };92 bundle.addModule(new ModuleTransport({93 code: 'transformed foo;',94 sourceCode: 'source foo',95 sourcePath: 'foo path'96 }));97 bundle.finalize();98 expect(bundle.getMinifiedSourceAndMap({dev: true})).toBe(minified);99 });100 });101 describe('sourcemap bundle', function() {102 it('should create sourcemap', function() {103 var p = new Bundle('test_url');104 p.addModule(new ModuleTransport({105 code: [106 'transformed foo',107 'transformed foo',108 'transformed foo',109 ].join('\n'),110 sourceCode: [111 'source foo',112 'source foo',113 'source foo',114 ].join('\n'),115 sourcePath: 'foo path',116 }));117 p.addModule(new ModuleTransport({118 code: [119 'transformed bar',120 'transformed bar',121 'transformed bar',122 ].join('\n'),123 sourceCode: [124 'source bar',125 'source bar',126 'source bar',127 ].join('\n'),128 sourcePath: 'bar path',129 }));130 p.setMainModuleId('foo');131 p.finalize({132 runBeforeMainModule: [],133 runMainModule: true,134 });135 var s = p.getSourceMap({dev: true});136 expect(s).toEqual(genSourceMap(p.getModules()));137 });138 it('should combine sourcemaps', function() {139 var p = new Bundle('test_url');140 p.addModule(new ModuleTransport({141 code: 'transformed foo;\n',142 map: {name: 'sourcemap foo'},143 sourceCode: 'source foo',144 sourcePath: 'foo path'145 }));146 p.addModule(new ModuleTransport({147 code: 'transformed foo;\n',148 map: {name: 'sourcemap bar'},149 sourceCode: 'source foo',150 sourcePath: 'foo path'151 }));152 p.addModule(new ModuleTransport({153 code: 'image module;\nimage module;',154 virtual: true,155 sourceCode: 'image module;\nimage module;',156 sourcePath: 'image.png',157 }));158 p.setMainModuleId('foo');159 p.finalize({160 runBeforeMainModule: ['InitializeJavaScriptAppEngine'],161 runMainModule: true,162 });163 var s = p.getSourceMap({dev: true});164 expect(s).toEqual({165 file: 'bundle.js',166 version: 3,167 sections: [168 { offset: { line: 0, column: 0 }, map: { name: 'sourcemap foo' } },169 { offset: { line: 2, column: 0 }, map: { name: 'sourcemap bar' } },170 {171 offset: {172 column: 0,173 line: 4174 },175 map: {176 file: 'image.png',177 mappings: 'AAAA;AACA;',178 names: [],179 sources: [ 'image.png' ],180 sourcesContent: ['image module;\nimage module;'],181 version: 3,182 }183 },184 {185 offset: {186 column: 0,187 line: 6188 },189 map: {190 file: 'require-InitializeJavaScriptAppEngine.js',191 mappings: 'AAAA;',192 names: [],193 sources: [ 'require-InitializeJavaScriptAppEngine.js' ],194 sourcesContent: [';require("InitializeJavaScriptAppEngine");'],195 version: 3,196 }197 },198 {199 offset: {200 column: 0,201 line: 7202 },203 map: {204 file: 'require-foo.js',205 mappings: 'AAAA;',206 names: [],207 sources: [ 'require-foo.js' ],208 sourcesContent: [';require("foo");'],209 version: 3,210 }211 },212 ],213 });214 });215 });216 describe('getAssets()', function() {217 it('should save and return asset objects', function() {218 var p = new Bundle('test_url');219 var asset1 = {};220 var asset2 = {};221 p.addAsset(asset1);222 p.addAsset(asset2);223 p.finalize();224 expect(p.getAssets()).toEqual([asset1, asset2]);225 });226 });227 describe('getJSModulePaths()', function() {228 it('should return module paths', function() {229 var p = new Bundle('test_url');230 p.addModule(new ModuleTransport({231 code: 'transformed foo;\n',232 sourceCode: 'source foo',233 sourcePath: 'foo path'234 }));235 p.addModule(new ModuleTransport({236 code: 'image module;\nimage module;',237 virtual: true,238 sourceCode: 'image module;\nimage module;',239 sourcePath: 'image.png',240 }));241 expect(p.getJSModulePaths()).toEqual(['foo path']);242 });243 });244});245function genSourceMap(modules) {246 var sourceMapGen = new SourceMapGenerator({file: 'bundle.js', version: 3});247 var bundleLineNo = 0;248 for (var i = 0; i < modules.length; i++) {249 var module = modules[i];250 var transformedCode = module.code;251 var sourcePath = module.sourcePath;252 var sourceCode = module.sourceCode;253 var transformedLineCount = 0;254 var lastCharNewLine = false;255 for (var t = 0; t < transformedCode.length; t++) {256 if (t === 0 || lastCharNewLine) {257 sourceMapGen.addMapping({258 generated: {line: bundleLineNo + 1, column: 0},259 original: {line: transformedLineCount + 1, column: 0},260 source: sourcePath261 });262 }263 lastCharNewLine = transformedCode[t] === '\n';264 if (lastCharNewLine) {265 transformedLineCount++;266 bundleLineNo++;267 }268 }269 bundleLineNo++;270 sourceMapGen.setSourceContent(271 sourcePath,272 sourceCode273 );274 }275 return sourceMapGen.toJSON();...
source-map-output.js
Source:source-map-output.js
1(function (tree) {2 tree.sourceMapOutput = function (options) {3 this._css = [];4 this._rootNode = options.rootNode;5 this._writeSourceMap = options.writeSourceMap;6 this._contentsMap = options.contentsMap;7 this._contentsIgnoredCharsMap = options.contentsIgnoredCharsMap;8 this._sourceMapFilename = options.sourceMapFilename;9 this._outputFilename = options.outputFilename;10 this._sourceMapURL = options.sourceMapURL;11 if (options.sourceMapBasepath) {12 this._sourceMapBasepath = options.sourceMapBasepath.replace(/\\/g, '/');13 }14 this._sourceMapRootpath = options.sourceMapRootpath;15 this._outputSourceFiles = options.outputSourceFiles;16 this._sourceMapGeneratorConstructor = options.sourceMapGenerator || require("source-map").SourceMapGenerator;17 if (this._sourceMapRootpath && this._sourceMapRootpath.charAt(this._sourceMapRootpath.length-1) !== '/') {18 this._sourceMapRootpath += '/';19 }20 this._lineNumber = 0;21 this._column = 0;22 };23 tree.sourceMapOutput.prototype.normalizeFilename = function(filename) {24 filename = filename.replace(/\\/g, '/');25 if (this._sourceMapBasepath && filename.indexOf(this._sourceMapBasepath) === 0) {26 filename = filename.substring(this._sourceMapBasepath.length);27 if (filename.charAt(0) === '\\' || filename.charAt(0) === '/') {28 filename = filename.substring(1);29 }30 }31 return (this._sourceMapRootpath || "") + filename;32 };33 tree.sourceMapOutput.prototype.add = function(chunk, fileInfo, index, mapLines) {34 //ignore adding empty strings35 if (!chunk) {36 return;37 }38 var lines,39 sourceLines,40 columns,41 sourceColumns,42 i;43 if (fileInfo) {44 var inputSource = this._contentsMap[fileInfo.filename];45 46 // remove vars/banner added to the top of the file47 if (this._contentsIgnoredCharsMap[fileInfo.filename]) {48 // adjust the index49 index -= this._contentsIgnoredCharsMap[fileInfo.filename];50 if (index < 0) { index = 0; }51 // adjust the source52 inputSource = inputSource.slice(this._contentsIgnoredCharsMap[fileInfo.filename]);53 }54 inputSource = inputSource.substring(0, index);55 sourceLines = inputSource.split("\n");56 sourceColumns = sourceLines[sourceLines.length-1];57 }58 lines = chunk.split("\n");59 columns = lines[lines.length-1];60 if (fileInfo) {61 if (!mapLines) {62 this._sourceMapGenerator.addMapping({ generated: { line: this._lineNumber + 1, column: this._column},63 original: { line: sourceLines.length, column: sourceColumns.length},64 source: this.normalizeFilename(fileInfo.filename)});65 } else {66 for(i = 0; i < lines.length; i++) {67 this._sourceMapGenerator.addMapping({ generated: { line: this._lineNumber + i + 1, column: i === 0 ? this._column : 0},68 original: { line: sourceLines.length + i, column: i === 0 ? sourceColumns.length : 0},69 source: this.normalizeFilename(fileInfo.filename)});70 }71 }72 }73 if (lines.length === 1) {74 this._column += columns.length;75 } else {76 this._lineNumber += lines.length - 1;77 this._column = columns.length;78 }79 this._css.push(chunk);80 };81 tree.sourceMapOutput.prototype.isEmpty = function() {82 return this._css.length === 0;83 };84 tree.sourceMapOutput.prototype.toCSS = function(env) {85 this._sourceMapGenerator = new this._sourceMapGeneratorConstructor({ file: this._outputFilename, sourceRoot: null });86 if (this._outputSourceFiles) {87 for(var filename in this._contentsMap) {88 if (this._contentsMap.hasOwnProperty(filename))89 {90 var source = this._contentsMap[filename];91 if (this._contentsIgnoredCharsMap[filename]) {92 source = source.slice(this._contentsIgnoredCharsMap[filename]);93 }94 this._sourceMapGenerator.setSourceContent(this.normalizeFilename(filename), source);95 }96 }97 }98 this._rootNode.genCSS(env, this);99 if (this._css.length > 0) {100 var sourceMapURL,101 sourceMapContent = JSON.stringify(this._sourceMapGenerator.toJSON());102 if (this._sourceMapURL) {103 sourceMapURL = this._sourceMapURL;104 } else if (this._sourceMapFilename) {105 sourceMapURL = this.normalizeFilename(this._sourceMapFilename);106 }107 if (this._writeSourceMap) {108 this._writeSourceMap(sourceMapContent);109 } else {110 sourceMapURL = "data:application/json," + encodeURIComponent(sourceMapContent);111 }112 if (sourceMapURL) {113 this._css.push("/*# sourceMappingURL=" + sourceMapURL + " */");114 }115 }116 return this._css.join('');117 };...
source-map-builder.js
Source:source-map-builder.js
1export default (SourceMapOutput, environment) => {2 class SourceMapBuilder {3 constructor(options) {4 this.options = options;5 }6 toCSS(rootNode, options, imports) {7 const sourceMapOutput = new SourceMapOutput(8 {9 contentsIgnoredCharsMap: imports.contentsIgnoredChars,10 rootNode,11 contentsMap: imports.contents,12 sourceMapFilename: this.options.sourceMapFilename,13 sourceMapURL: this.options.sourceMapURL,14 outputFilename: this.options.sourceMapOutputFilename,15 sourceMapBasepath: this.options.sourceMapBasepath,16 sourceMapRootpath: this.options.sourceMapRootpath,17 outputSourceFiles: this.options.outputSourceFiles,18 sourceMapGenerator: this.options.sourceMapGenerator,19 sourceMapFileInline: this.options.sourceMapFileInline, 20 disableSourcemapAnnotation: this.options.disableSourcemapAnnotation21 });22 const css = sourceMapOutput.toCSS(options);23 this.sourceMap = sourceMapOutput.sourceMap;24 this.sourceMapURL = sourceMapOutput.sourceMapURL;25 if (this.options.sourceMapInputFilename) {26 this.sourceMapInputFilename = sourceMapOutput.normalizeFilename(this.options.sourceMapInputFilename);27 }28 if (this.options.sourceMapBasepath !== undefined && this.sourceMapURL !== undefined) {29 this.sourceMapURL = sourceMapOutput.removeBasepath(this.sourceMapURL);30 }31 return css + this.getCSSAppendage();32 }33 getCSSAppendage() {34 let sourceMapURL = this.sourceMapURL;35 if (this.options.sourceMapFileInline) {36 if (this.sourceMap === undefined) {37 return '';38 }39 sourceMapURL = `data:application/json;base64,${environment.encodeBase64(this.sourceMap)}`;40 }41 if (this.options.disableSourcemapAnnotation) {42 return '';43 }44 if (sourceMapURL) {45 return `/*# sourceMappingURL=${sourceMapURL} */`;46 }47 return '';48 }49 getExternalSourceMap() {50 return this.sourceMap;51 }52 setExternalSourceMap(sourceMap) {53 this.sourceMap = sourceMap;54 }55 isInline() {56 return this.options.sourceMapFileInline;57 }58 getSourceMapURL() {59 return this.sourceMapURL;60 }61 getOutputFilename() {62 return this.options.sourceMapOutputFilename;63 }64 getInputFilename() {65 return this.sourceMapInputFilename;66 }67 }68 return SourceMapBuilder;...
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.screenshot({ path: 'google.png' });7 await browser.close();8})();9const { test, expect } = require('@playwright/test');10test('basic test', async ({ page }) => {11 const title = page.locator('text=Get started');12 await expect(title).toBeVisible();13});14 ✓ sample.spec.js (3s)15 1 passed (3s)16const { test, expect } = require
Using AI Code Generation
1const { chromium } = require('playwright');2(async () => {3 const browser = await chromium.launch({ headless: false });4 const context = await browser.newContext();5 const page = await context.newPage();6 const source = await page.source();7 console.log(source);8 await browser.close();9})();10const { chromium } = require('playwright');11(async () => {12 const browser = await chromium.launch({ headless: false });13 const context = await browser.newContext();14 const page = await context.newPage();15 const source = await page.source();16 console.log(source);17 await browser.close();18})();19const { chromium } = require('playwright');20(async () => {21 const browser = await chromium.launch({ headless: false });22 const context = await browser.newContext();23 const page = await context.newPage();24 const source = await page.source();25 console.log(source);26 await browser.close();27})();28const { chromium } = require('playwright');29(async () => {30 const browser = await chromium.launch({ headless: false });31 const context = await browser.newContext();32 const page = await context.newPage();33 const source = await page.source();34 console.log(source);35 await browser.close();36})();37const { chromium } = require('playwright');38(async () => {39 const browser = await chromium.launch({ headless: false });40 const context = await browser.newContext();41 const page = await context.newPage();42 const source = await page.source();43 console.log(source);44 await browser.close();45})();46const { chromium } = require('playwright');47(async () => {48 const browser = await chromium.launch({ headless: false });49 const context = await browser.newContext();50 const page = await context.newPage();
Using AI Code Generation
1const { chromium } = require('playwright');2(async () => {3 const browser = await chromium.launch({4 });5 const page = await browser.newPage();6 await page.screenshot({ path: 'google.png' });7 await browser.close();8})();9const { chromium } = require('playwright');10(async () => {11 const browser = await chromium.launch({12 });13 const page = await browser.newPage();14 await page.screenshot({ path: 'google.png' });15 await browser.close();16})();17const { chromium } = require('playwright');18(async () => {19 const browser = await chromium.launch({20 });21 const page = await browser.newPage();22 await page.screenshot({ path: 'google.png' });23 await browser.close();24})();25const { chromium } = require('playwright');26(async () => {27 const browser = await chromium.launch({28 });29 const page = await browser.newPage();30 await page.screenshot({ path: 'google.png' });31 await browser.close();32})();33const { chromium } = require('playwright');34(async () => {35 const browser = await chromium.launch({36 });37 const page = await browser.newPage();38 await page.screenshot({ path: 'google.png' });39 await browser.close();40})();41const { chromium } = require('playwright');42(async () => {43 const browser = await chromium.launch({44 });45 const page = await browser.newPage();46 await page.screenshot({ path: 'google.png'
Using AI Code Generation
1const { Playwright } = require('playwright');2const { chromium } = Playwright;3(async () => {4 const browser = await chromium.launch();5 const context = await browser.newContext();6 const page = await context.newPage();7 const sources = await page.source();8 console.log(sources);9 await browser.close();10})();
Using AI Code Generation
1const { chromium } = require('playwright');2const { source } = require('playwright/internal');3(async () => {4 const browser = await chromium.launch();5 const context = await browser.newContext();6 const page = await context.newPage();7 const html = await source(page);8 console.log(html);9 await browser.close();10})();
Using AI Code Generation
1const { source } = require('playwright');2const { chromium } = source;3(async () => {4 const browser = await chromium.launch();5 const context = await browser.newContext();6 const page = await context.newPage();7 await page.screenshot({ path: 'example.png' });8 await browser.close();9})();10const { source } = require('playwright');11const { firefox } = source;12(async () => {13 const browser = await firefox.launch();14 const context = await browser.newContext();15 const page = await context.newPage();16 await page.screenshot({ path: 'example.png' });17 await browser.close();18})();19const { source } = require('playwright');20const { webkit } = source;21(async () => {22 const browser = await webkit.launch();23 const context = await browser.newContext();24 const page = await context.newPage();25 await page.screenshot({ path: 'example.png' });26 await browser.close();27})();28const { source } = require('playwright');29const { chromium } = source;30(async () => {31 const browser = await chromium.launch();32 const context = await browser.newContext();33 const page = await context.newPage();34 await page.screenshot({ path: 'example.png' });35 await browser.close();36})();37const { source } = require('playwright');38const { firefox } = source;39(async () => {40 const browser = await firefox.launch();41 const context = await browser.newContext();42 const page = await context.newPage();43 await page.screenshot({ path: 'example.png' });44 await browser.close();45})();46const { source } = require('playwright');47const { webkit } = source;
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 const source = await page.source();7 console.log(source);8 await browser.close();9})();
Using AI Code Generation
1const { Playwright } = require('playwright');2const playwright = Playwright.create();3const { chromium } = playwright;4const browser = await chromium.launch({ headless: false });5const page = await browser.newPage();6await page.screenshot({ path: 'screenshot.png' });7await browser.close();8const { Playwright } = require('playwright');9const playwright = Playwright.create();10const { chromium } = playwright;11const browser = await chromium.launch({ headless: false });12const page = await browser.newPage();13await page.screenshot({ path: 'screenshot.png' });14await browser.close();15const { Playwright } = require('playwright');16const playwright = Playwright.create();17const { chromium } = playwright;18const browser = await chromium.launch({ headless: false });19const page = await browser.newPage();20await page.screenshot({ path: 'screenshot.png' });21await browser.close();22const { Playwright } = require('playwright');23const playwright = Playwright.create();24const { chromium } = playwright;25const browser = await chromium.launch({ headless: false });26const page = await browser.newPage();27await page.screenshot({ path: 'screenshot.png' });28await browser.close();29const { Playwright } = require('playwright');30const playwright = Playwright.create();31const { chromium } = playwright;32const browser = await chromium.launch({ headless: false });33const page = await browser.newPage();34await page.screenshot({ path: 'screenshot.png' });35await browser.close();36const { Playwright } = require('playwright');37const playwright = Playwright.create();38const { chromium } = playwright;39const browser = await chromium.launch({ headless: false });40const page = await browser.newPage();
Using AI Code Generation
1const { Page } = require('playwright-core/lib/server/page');2Page.prototype.source = async function() {3 return await this._frameManager.mainFrame()._mainContext._delegate._source();4};5(async () => {6 const browser = await chromium.launch({ headless: false });7 const page = await browser.newPage();8 const source = await page.source();9 console.log(source);10 await browser.close();11})();12 body {13 font-family: 'Open Sans', sans-serif;14 }15 .container {16 margin-top: 100px;17 }18 .lead {19 font-size: 1.25rem;20 }21 a {22 color: #007bff;23 text-decoration: none;24 background-color: transparent;25 }26 a:hover {27 color: #0056b3;28 text-decoration: underline;29 }30 a:not([href]):not([tabindex]) {31 color: inherit;32 text-decoration: none;33 }34 a:not([href]):not([tabindex]):focus, a:not([href]):not([tabindex]):hover {35 color: inherit;36 text-decoration: none;37 }38 a:not([href]):not([tabindex]):focus {39 outline: 0;40 }41 .small {42 font-size: 80%;43 }
Using AI Code Generation
1const { sources } = require('@playwright/test');2const { test } = sources;3test('Test 1', async ({ page }) => {4});5test('Test 2', async ({ page }) => {6});7test('Test 3', async ({ page }) => {8});9test('Test 4', async ({ page }) => {10});11test('Test 5', async ({ page }) => {12});13test('Test 6', async ({ page }) => {14});15test('Test 7', async ({ page }) => {16});17test('Test 8', async ({ page }) => {18});19test('Test 9', async ({ page }) => {20});21test('Test 10', async ({ page }) => {22});23test('Test 11', async ({ page }) => {24});25test('Test 12', async ({ page }) => {26});27test('Test 13', async ({ page }) => {28});
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!!