aboutsummaryrefslogtreecommitdiff
path: root/node_modules/webpack-sources/lib/ReplaceSource.js
diff options
context:
space:
mode:
Diffstat (limited to 'node_modules/webpack-sources/lib/ReplaceSource.js')
-rw-r--r--node_modules/webpack-sources/lib/ReplaceSource.js192
1 files changed, 192 insertions, 0 deletions
diff --git a/node_modules/webpack-sources/lib/ReplaceSource.js b/node_modules/webpack-sources/lib/ReplaceSource.js
new file mode 100644
index 000000000..63087d6de
--- /dev/null
+++ b/node_modules/webpack-sources/lib/ReplaceSource.js
@@ -0,0 +1,192 @@
+/*
+ MIT License http://www.opensource.org/licenses/mit-license.php
+ Author Tobias Koppers @sokra
+*/
+var Source = require("./Source");
+var SourceNode = require("source-map").SourceNode;
+var SourceListMap = require("source-list-map").SourceListMap;
+var fromStringWithSourceMap = require("source-list-map").fromStringWithSourceMap;
+var SourceMapConsumer = require("source-map").SourceMapConsumer;
+
+function ReplaceSource(source, name) {
+ Source.call(this);
+ this._source = source;
+ this._name = name;
+ this.replacements = [];
+}
+module.exports = ReplaceSource;
+
+ReplaceSource.prototype = Object.create(Source.prototype);
+ReplaceSource.prototype.constructor = ReplaceSource;
+
+ReplaceSource.prototype.replace = function(start, end, newValue) {
+ if(typeof newValue !== "string")
+ throw new Error("insertion must be a string, but is a " + typeof newValue);
+ this.replacements.push([start, end, newValue, this.replacements.length]);
+};
+
+ReplaceSource.prototype.insert = function(pos, newValue) {
+ if(typeof newValue !== "string")
+ throw new Error("insertion must be a string, but is a " + typeof newValue + ": " + newValue);
+ this.replacements.push([pos, pos - 1, newValue, this.replacements.length]);
+};
+
+ReplaceSource.prototype.source = function(options) {
+ return this._replaceString(this._source.source());
+};
+
+ReplaceSource.prototype._sortReplacements = function() {
+ this.replacements.sort(function(a, b) {
+ var diff = b[1] - a[1];
+ if(diff !== 0)
+ return diff;
+ diff = b[0] - a[0];
+ if(diff !== 0)
+ return diff;
+ return b[3] - a[3];
+ });
+};
+
+ReplaceSource.prototype._replaceString = function(str) {
+ if(typeof str !== "string")
+ throw new Error("str must be a string, but is a " + typeof str + ": " + str);
+ this._sortReplacements();
+ var result = [str];
+ this.replacements.forEach(function(repl) {
+ var remSource = result.pop();
+ var splitted1 = this._splitString(remSource, Math.floor(repl[1] + 1));
+ var splitted2 = this._splitString(splitted1[0], Math.floor(repl[0]));
+ result.push(splitted1[1], repl[2], splitted2[0]);
+ }, this);
+ result = result.reverse();
+ return result.join("");
+};
+
+require("./SourceAndMapMixin")(ReplaceSource.prototype);
+
+ReplaceSource.prototype.node = function(options) {
+ this._sortReplacements();
+ var result = [this._source.node(options)];
+ this.replacements.forEach(function(repl) {
+ var remSource = result.pop();
+ var splitted1 = this._splitSourceNode(remSource, Math.floor(repl[1] + 1));
+ var splitted2;
+ if(Array.isArray(splitted1)) {
+ splitted2 = this._splitSourceNode(splitted1[0], Math.floor(repl[0]));
+ if(Array.isArray(splitted2)) {
+ result.push(splitted1[1], this._replacementToSourceNode(splitted2[1], repl[2]), splitted2[0]);
+ } else {
+ result.push(splitted1[1], this._replacementToSourceNode(splitted1[1], repl[2]), splitted1[0]);
+ }
+ } else {
+ splitted2 = this._splitSourceNode(remSource, Math.floor(repl[0]));
+ if(Array.isArray(splitted2)) {
+ result.push(this._replacementToSourceNode(splitted2[1], repl[2]), splitted2[0]);
+ } else {
+ result.push(repl[2], remSource);
+ }
+ }
+ }, this);
+ result = result.reverse();
+ return new SourceNode(null, null, null, result);
+};
+
+ReplaceSource.prototype.listMap = function(options) {
+ this._sortReplacements();
+ var map = this._source.listMap(options);
+ var currentIndex = 0;
+ var replacements = this.replacements;
+ var idxReplacement = replacements.length - 1;
+ var removeChars = 0;
+ map = map.mapGeneratedCode(function(str) {
+ var newCurrentIndex = currentIndex + str.length;
+ if(removeChars > str.length) {
+ removeChars -= str.length;
+ str = "";
+ } else {
+ if(removeChars > 0) {
+ str = str.substr(removeChars);
+ currentIndex += removeChars;
+ removeChars = 0;
+ }
+ var finalStr = "";
+ while(idxReplacement >= 0 && replacements[idxReplacement][0] < newCurrentIndex) {
+ var repl = replacements[idxReplacement];
+ var start = Math.floor(repl[0]);
+ var end = Math.floor(repl[1] + 1);
+ var before = str.substr(0, Math.max(0, start - currentIndex));
+ if(end <= newCurrentIndex) {
+ var after = str.substr(Math.max(0, end - currentIndex));
+ finalStr += before + repl[2];
+ str = after;
+ currentIndex = Math.max(currentIndex, end);
+ } else {
+ finalStr += before + repl[2];
+ str = "";
+ removeChars = end - newCurrentIndex;
+ }
+ idxReplacement--;
+ }
+ str = finalStr + str;
+ }
+ currentIndex = newCurrentIndex;
+ return str;
+ });
+ var extraCode = "";
+ while(idxReplacement >= 0) {
+ extraCode += replacements[idxReplacement][2];
+ idxReplacement--;
+ }
+ if(extraCode) {
+ map.add(extraCode);
+ }
+ return map;
+};
+
+ReplaceSource.prototype._replacementToSourceNode = function(oldNode, newString) {
+ var map = oldNode.toStringWithSourceMap({
+ file: "?"
+ }).map;
+ var original = new SourceMapConsumer(map.toJSON()).originalPositionFor({
+ line: 1,
+ column: 0
+ });
+ if(original) {
+ return new SourceNode(original.line, original.column, original.source, newString);
+ } else {
+ return newString;
+ }
+};
+
+ReplaceSource.prototype._splitSourceNode = function(node, position) {
+ if(typeof node === "string") {
+ if(node.length <= position) return position - node.length;
+ return position <= 0 ? ["", node] : [node.substr(0, position), node.substr(position)];
+ } else {
+ for(var i = 0; i < node.children.length; i++) {
+ position = this._splitSourceNode(node.children[i], position);
+ if(Array.isArray(position)) {
+ var leftNode = new SourceNode(
+ node.line,
+ node.column,
+ node.source,
+ node.children.slice(0, i).concat([position[0]]),
+ node.name
+ );
+ var rightNode = new SourceNode(
+ node.line,
+ node.column,
+ node.source, [position[1]].concat(node.children.slice(i + 1)),
+ node.name
+ );
+ leftNode.sourceContents = node.sourceContents;
+ return [leftNode, rightNode];
+ }
+ }
+ return position;
+ }
+};
+
+ReplaceSource.prototype._splitString = function(str, position) {
+ return position <= 0 ? ["", str] : [str.substr(0, position), str.substr(position)];
+};