@ -0,0 +1,339 @@ |
|||||||
|
GNU GENERAL PUBLIC LICENSE |
||||||
|
Version 2, June 1991 |
||||||
|
|
||||||
|
Copyright (C) 1989, 1991 Free Software Foundation, Inc., |
||||||
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
||||||
|
Everyone is permitted to copy and distribute verbatim copies |
||||||
|
of this license document, but changing it is not allowed. |
||||||
|
|
||||||
|
Preamble |
||||||
|
|
||||||
|
The licenses for most software are designed to take away your |
||||||
|
freedom to share and change it. By contrast, the GNU General Public |
||||||
|
License is intended to guarantee your freedom to share and change free |
||||||
|
software--to make sure the software is free for all its users. This |
||||||
|
General Public License applies to most of the Free Software |
||||||
|
Foundation's software and to any other program whose authors commit to |
||||||
|
using it. (Some other Free Software Foundation software is covered by |
||||||
|
the GNU Lesser General Public License instead.) You can apply it to |
||||||
|
your programs, too. |
||||||
|
|
||||||
|
When we speak of free software, we are referring to freedom, not |
||||||
|
price. Our General Public Licenses are designed to make sure that you |
||||||
|
have the freedom to distribute copies of free software (and charge for |
||||||
|
this service if you wish), that you receive source code or can get it |
||||||
|
if you want it, that you can change the software or use pieces of it |
||||||
|
in new free programs; and that you know you can do these things. |
||||||
|
|
||||||
|
To protect your rights, we need to make restrictions that forbid |
||||||
|
anyone to deny you these rights or to ask you to surrender the rights. |
||||||
|
These restrictions translate to certain responsibilities for you if you |
||||||
|
distribute copies of the software, or if you modify it. |
||||||
|
|
||||||
|
For example, if you distribute copies of such a program, whether |
||||||
|
gratis or for a fee, you must give the recipients all the rights that |
||||||
|
you have. You must make sure that they, too, receive or can get the |
||||||
|
source code. And you must show them these terms so they know their |
||||||
|
rights. |
||||||
|
|
||||||
|
We protect your rights with two steps: (1) copyright the software, and |
||||||
|
(2) offer you this license which gives you legal permission to copy, |
||||||
|
distribute and/or modify the software. |
||||||
|
|
||||||
|
Also, for each author's protection and ours, we want to make certain |
||||||
|
that everyone understands that there is no warranty for this free |
||||||
|
software. If the software is modified by someone else and passed on, we |
||||||
|
want its recipients to know that what they have is not the original, so |
||||||
|
that any problems introduced by others will not reflect on the original |
||||||
|
authors' reputations. |
||||||
|
|
||||||
|
Finally, any free program is threatened constantly by software |
||||||
|
patents. We wish to avoid the danger that redistributors of a free |
||||||
|
program will individually obtain patent licenses, in effect making the |
||||||
|
program proprietary. To prevent this, we have made it clear that any |
||||||
|
patent must be licensed for everyone's free use or not licensed at all. |
||||||
|
|
||||||
|
The precise terms and conditions for copying, distribution and |
||||||
|
modification follow. |
||||||
|
|
||||||
|
GNU GENERAL PUBLIC LICENSE |
||||||
|
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION |
||||||
|
|
||||||
|
0. This License applies to any program or other work which contains |
||||||
|
a notice placed by the copyright holder saying it may be distributed |
||||||
|
under the terms of this General Public License. The "Program", below, |
||||||
|
refers to any such program or work, and a "work based on the Program" |
||||||
|
means either the Program or any derivative work under copyright law: |
||||||
|
that is to say, a work containing the Program or a portion of it, |
||||||
|
either verbatim or with modifications and/or translated into another |
||||||
|
language. (Hereinafter, translation is included without limitation in |
||||||
|
the term "modification".) Each licensee is addressed as "you". |
||||||
|
|
||||||
|
Activities other than copying, distribution and modification are not |
||||||
|
covered by this License; they are outside its scope. The act of |
||||||
|
running the Program is not restricted, and the output from the Program |
||||||
|
is covered only if its contents constitute a work based on the |
||||||
|
Program (independent of having been made by running the Program). |
||||||
|
Whether that is true depends on what the Program does. |
||||||
|
|
||||||
|
1. You may copy and distribute verbatim copies of the Program's |
||||||
|
source code as you receive it, in any medium, provided that you |
||||||
|
conspicuously and appropriately publish on each copy an appropriate |
||||||
|
copyright notice and disclaimer of warranty; keep intact all the |
||||||
|
notices that refer to this License and to the absence of any warranty; |
||||||
|
and give any other recipients of the Program a copy of this License |
||||||
|
along with the Program. |
||||||
|
|
||||||
|
You may charge a fee for the physical act of transferring a copy, and |
||||||
|
you may at your option offer warranty protection in exchange for a fee. |
||||||
|
|
||||||
|
2. You may modify your copy or copies of the Program or any portion |
||||||
|
of it, thus forming a work based on the Program, and copy and |
||||||
|
distribute such modifications or work under the terms of Section 1 |
||||||
|
above, provided that you also meet all of these conditions: |
||||||
|
|
||||||
|
a) You must cause the modified files to carry prominent notices |
||||||
|
stating that you changed the files and the date of any change. |
||||||
|
|
||||||
|
b) You must cause any work that you distribute or publish, that in |
||||||
|
whole or in part contains or is derived from the Program or any |
||||||
|
part thereof, to be licensed as a whole at no charge to all third |
||||||
|
parties under the terms of this License. |
||||||
|
|
||||||
|
c) If the modified program normally reads commands interactively |
||||||
|
when run, you must cause it, when started running for such |
||||||
|
interactive use in the most ordinary way, to print or display an |
||||||
|
announcement including an appropriate copyright notice and a |
||||||
|
notice that there is no warranty (or else, saying that you provide |
||||||
|
a warranty) and that users may redistribute the program under |
||||||
|
these conditions, and telling the user how to view a copy of this |
||||||
|
License. (Exception: if the Program itself is interactive but |
||||||
|
does not normally print such an announcement, your work based on |
||||||
|
the Program is not required to print an announcement.) |
||||||
|
|
||||||
|
These requirements apply to the modified work as a whole. If |
||||||
|
identifiable sections of that work are not derived from the Program, |
||||||
|
and can be reasonably considered independent and separate works in |
||||||
|
themselves, then this License, and its terms, do not apply to those |
||||||
|
sections when you distribute them as separate works. But when you |
||||||
|
distribute the same sections as part of a whole which is a work based |
||||||
|
on the Program, the distribution of the whole must be on the terms of |
||||||
|
this License, whose permissions for other licensees extend to the |
||||||
|
entire whole, and thus to each and every part regardless of who wrote it. |
||||||
|
|
||||||
|
Thus, it is not the intent of this section to claim rights or contest |
||||||
|
your rights to work written entirely by you; rather, the intent is to |
||||||
|
exercise the right to control the distribution of derivative or |
||||||
|
collective works based on the Program. |
||||||
|
|
||||||
|
In addition, mere aggregation of another work not based on the Program |
||||||
|
with the Program (or with a work based on the Program) on a volume of |
||||||
|
a storage or distribution medium does not bring the other work under |
||||||
|
the scope of this License. |
||||||
|
|
||||||
|
3. You may copy and distribute the Program (or a work based on it, |
||||||
|
under Section 2) in object code or executable form under the terms of |
||||||
|
Sections 1 and 2 above provided that you also do one of the following: |
||||||
|
|
||||||
|
a) Accompany it with the complete corresponding machine-readable |
||||||
|
source code, which must be distributed under the terms of Sections |
||||||
|
1 and 2 above on a medium customarily used for software interchange; or, |
||||||
|
|
||||||
|
b) Accompany it with a written offer, valid for at least three |
||||||
|
years, to give any third party, for a charge no more than your |
||||||
|
cost of physically performing source distribution, a complete |
||||||
|
machine-readable copy of the corresponding source code, to be |
||||||
|
distributed under the terms of Sections 1 and 2 above on a medium |
||||||
|
customarily used for software interchange; or, |
||||||
|
|
||||||
|
c) Accompany it with the information you received as to the offer |
||||||
|
to distribute corresponding source code. (This alternative is |
||||||
|
allowed only for noncommercial distribution and only if you |
||||||
|
received the program in object code or executable form with such |
||||||
|
an offer, in accord with Subsection b above.) |
||||||
|
|
||||||
|
The source code for a work means the preferred form of the work for |
||||||
|
making modifications to it. For an executable work, complete source |
||||||
|
code means all the source code for all modules it contains, plus any |
||||||
|
associated interface definition files, plus the scripts used to |
||||||
|
control compilation and installation of the executable. However, as a |
||||||
|
special exception, the source code distributed need not include |
||||||
|
anything that is normally distributed (in either source or binary |
||||||
|
form) with the major components (compiler, kernel, and so on) of the |
||||||
|
operating system on which the executable runs, unless that component |
||||||
|
itself accompanies the executable. |
||||||
|
|
||||||
|
If distribution of executable or object code is made by offering |
||||||
|
access to copy from a designated place, then offering equivalent |
||||||
|
access to copy the source code from the same place counts as |
||||||
|
distribution of the source code, even though third parties are not |
||||||
|
compelled to copy the source along with the object code. |
||||||
|
|
||||||
|
4. You may not copy, modify, sublicense, or distribute the Program |
||||||
|
except as expressly provided under this License. Any attempt |
||||||
|
otherwise to copy, modify, sublicense or distribute the Program is |
||||||
|
void, and will automatically terminate your rights under this License. |
||||||
|
However, parties who have received copies, or rights, from you under |
||||||
|
this License will not have their licenses terminated so long as such |
||||||
|
parties remain in full compliance. |
||||||
|
|
||||||
|
5. You are not required to accept this License, since you have not |
||||||
|
signed it. However, nothing else grants you permission to modify or |
||||||
|
distribute the Program or its derivative works. These actions are |
||||||
|
prohibited by law if you do not accept this License. Therefore, by |
||||||
|
modifying or distributing the Program (or any work based on the |
||||||
|
Program), you indicate your acceptance of this License to do so, and |
||||||
|
all its terms and conditions for copying, distributing or modifying |
||||||
|
the Program or works based on it. |
||||||
|
|
||||||
|
6. Each time you redistribute the Program (or any work based on the |
||||||
|
Program), the recipient automatically receives a license from the |
||||||
|
original licensor to copy, distribute or modify the Program subject to |
||||||
|
these terms and conditions. You may not impose any further |
||||||
|
restrictions on the recipients' exercise of the rights granted herein. |
||||||
|
You are not responsible for enforcing compliance by third parties to |
||||||
|
this License. |
||||||
|
|
||||||
|
7. If, as a consequence of a court judgment or allegation of patent |
||||||
|
infringement or for any other reason (not limited to patent issues), |
||||||
|
conditions are imposed on you (whether by court order, agreement or |
||||||
|
otherwise) that contradict the conditions of this License, they do not |
||||||
|
excuse you from the conditions of this License. If you cannot |
||||||
|
distribute so as to satisfy simultaneously your obligations under this |
||||||
|
License and any other pertinent obligations, then as a consequence you |
||||||
|
may not distribute the Program at all. For example, if a patent |
||||||
|
license would not permit royalty-free redistribution of the Program by |
||||||
|
all those who receive copies directly or indirectly through you, then |
||||||
|
the only way you could satisfy both it and this License would be to |
||||||
|
refrain entirely from distribution of the Program. |
||||||
|
|
||||||
|
If any portion of this section is held invalid or unenforceable under |
||||||
|
any particular circumstance, the balance of the section is intended to |
||||||
|
apply and the section as a whole is intended to apply in other |
||||||
|
circumstances. |
||||||
|
|
||||||
|
It is not the purpose of this section to induce you to infringe any |
||||||
|
patents or other property right claims or to contest validity of any |
||||||
|
such claims; this section has the sole purpose of protecting the |
||||||
|
integrity of the free software distribution system, which is |
||||||
|
implemented by public license practices. Many people have made |
||||||
|
generous contributions to the wide range of software distributed |
||||||
|
through that system in reliance on consistent application of that |
||||||
|
system; it is up to the author/donor to decide if he or she is willing |
||||||
|
to distribute software through any other system and a licensee cannot |
||||||
|
impose that choice. |
||||||
|
|
||||||
|
This section is intended to make thoroughly clear what is believed to |
||||||
|
be a consequence of the rest of this License. |
||||||
|
|
||||||
|
8. If the distribution and/or use of the Program is restricted in |
||||||
|
certain countries either by patents or by copyrighted interfaces, the |
||||||
|
original copyright holder who places the Program under this License |
||||||
|
may add an explicit geographical distribution limitation excluding |
||||||
|
those countries, so that distribution is permitted only in or among |
||||||
|
countries not thus excluded. In such case, this License incorporates |
||||||
|
the limitation as if written in the body of this License. |
||||||
|
|
||||||
|
9. The Free Software Foundation may publish revised and/or new versions |
||||||
|
of the General Public License from time to time. Such new versions will |
||||||
|
be similar in spirit to the present version, but may differ in detail to |
||||||
|
address new problems or concerns. |
||||||
|
|
||||||
|
Each version is given a distinguishing version number. If the Program |
||||||
|
specifies a version number of this License which applies to it and "any |
||||||
|
later version", you have the option of following the terms and conditions |
||||||
|
either of that version or of any later version published by the Free |
||||||
|
Software Foundation. If the Program does not specify a version number of |
||||||
|
this License, you may choose any version ever published by the Free Software |
||||||
|
Foundation. |
||||||
|
|
||||||
|
10. If you wish to incorporate parts of the Program into other free |
||||||
|
programs whose distribution conditions are different, write to the author |
||||||
|
to ask for permission. For software which is copyrighted by the Free |
||||||
|
Software Foundation, write to the Free Software Foundation; we sometimes |
||||||
|
make exceptions for this. Our decision will be guided by the two goals |
||||||
|
of preserving the free status of all derivatives of our free software and |
||||||
|
of promoting the sharing and reuse of software generally. |
||||||
|
|
||||||
|
NO WARRANTY |
||||||
|
|
||||||
|
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY |
||||||
|
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN |
||||||
|
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES |
||||||
|
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED |
||||||
|
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF |
||||||
|
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS |
||||||
|
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE |
||||||
|
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, |
||||||
|
REPAIR OR CORRECTION. |
||||||
|
|
||||||
|
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING |
||||||
|
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR |
||||||
|
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, |
||||||
|
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING |
||||||
|
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED |
||||||
|
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY |
||||||
|
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER |
||||||
|
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE |
||||||
|
POSSIBILITY OF SUCH DAMAGES. |
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS |
||||||
|
|
||||||
|
How to Apply These Terms to Your New Programs |
||||||
|
|
||||||
|
If you develop a new program, and you want it to be of the greatest |
||||||
|
possible use to the public, the best way to achieve this is to make it |
||||||
|
free software which everyone can redistribute and change under these terms. |
||||||
|
|
||||||
|
To do so, attach the following notices to the program. It is safest |
||||||
|
to attach them to the start of each source file to most effectively |
||||||
|
convey the exclusion of warranty; and each file should have at least |
||||||
|
the "copyright" line and a pointer to where the full notice is found. |
||||||
|
|
||||||
|
<one line to give the program's name and a brief idea of what it does.> |
||||||
|
Copyright (C) <year> <name of author> |
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify |
||||||
|
it under the terms of the GNU General Public License as published by |
||||||
|
the Free Software Foundation; either version 2 of the License, or |
||||||
|
(at your option) any later version. |
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful, |
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||||
|
GNU General Public License for more details. |
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License along |
||||||
|
with this program; if not, write to the Free Software Foundation, Inc., |
||||||
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |
||||||
|
|
||||||
|
Also add information on how to contact you by electronic and paper mail. |
||||||
|
|
||||||
|
If the program is interactive, make it output a short notice like this |
||||||
|
when it starts in an interactive mode: |
||||||
|
|
||||||
|
Gnomovision version 69, Copyright (C) year name of author |
||||||
|
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. |
||||||
|
This is free software, and you are welcome to redistribute it |
||||||
|
under certain conditions; type `show c' for details. |
||||||
|
|
||||||
|
The hypothetical commands `show w' and `show c' should show the appropriate |
||||||
|
parts of the General Public License. Of course, the commands you use may |
||||||
|
be called something other than `show w' and `show c'; they could even be |
||||||
|
mouse-clicks or menu items--whatever suits your program. |
||||||
|
|
||||||
|
You should also get your employer (if you work as a programmer) or your |
||||||
|
school, if any, to sign a "copyright disclaimer" for the program, if |
||||||
|
necessary. Here is a sample; alter the names: |
||||||
|
|
||||||
|
Yoyodyne, Inc., hereby disclaims all copyright interest in the program |
||||||
|
`Gnomovision' (which makes passes at compilers) written by James Hacker. |
||||||
|
|
||||||
|
<signature of Ty Coon>, 1 April 1989 |
||||||
|
Ty Coon, President of Vice |
||||||
|
|
||||||
|
This General Public License does not permit incorporating your program into |
||||||
|
proprietary programs. If your program is a subroutine library, you may |
||||||
|
consider it more useful to permit linking proprietary applications with the |
||||||
|
library. If this is what you want to do, use the GNU Lesser General |
||||||
|
Public License instead of this License. |
@ -0,0 +1,93 @@ |
|||||||
|
let gulp = require('gulp'), |
||||||
|
sass = require('gulp-sass'), |
||||||
|
sourcemaps = require('gulp-sourcemaps'), |
||||||
|
$ = require('gulp-load-plugins')(), |
||||||
|
cleanCss = require('gulp-clean-css'), |
||||||
|
rename = require('gulp-rename'), |
||||||
|
postcss = require('gulp-postcss'), |
||||||
|
autoprefixer = require('autoprefixer'), |
||||||
|
postcssInlineSvg = require('postcss-inline-svg'), |
||||||
|
browserSync = require('browser-sync').create() |
||||||
|
pxtorem = require('postcss-pxtorem'), |
||||||
|
postcssProcessors = [ |
||||||
|
postcssInlineSvg({ |
||||||
|
removeFill: true, |
||||||
|
paths: ['./node_modules/bootstrap-icons/icons'] |
||||||
|
}), |
||||||
|
pxtorem({ |
||||||
|
propList: ['font', 'font-size', 'line-height', 'letter-spacing', '*margin*', '*padding*'], |
||||||
|
mediaQuery: true |
||||||
|
}) |
||||||
|
]; |
||||||
|
|
||||||
|
const paths = { |
||||||
|
scss: { |
||||||
|
src: './scss/style.scss', |
||||||
|
dest: './css', |
||||||
|
watch: './scss/**/*.scss', |
||||||
|
bootstrap: './node_modules/bootstrap/scss/bootstrap.scss', |
||||||
|
}, |
||||||
|
js: { |
||||||
|
bootstrap: './node_modules/bootstrap/dist/js/bootstrap.min.js', |
||||||
|
jquery: './node_modules/jquery/dist/jquery.min.js', |
||||||
|
popper: './node_modules/popper.js/dist/umd/popper.min.js', |
||||||
|
poppermap: './node_modules/popper.js/dist/umd/popper.min.js.map', |
||||||
|
barrio: '../../contrib/bootstrap_barrio/js/barrio.js', |
||||||
|
dest: './js' |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// Compile sass into CSS & auto-inject into browsers
|
||||||
|
function styles () { |
||||||
|
return gulp.src([paths.scss.bootstrap, paths.scss.src]) |
||||||
|
.pipe(sourcemaps.init()) |
||||||
|
.pipe(sass({ |
||||||
|
includePaths: [ |
||||||
|
'./node_modules/bootstrap/scss', |
||||||
|
'../../contrib/bootstrap_barrio/scss' |
||||||
|
] |
||||||
|
}).on('error', sass.logError)) |
||||||
|
.pipe($.postcss(postcssProcessors)) |
||||||
|
.pipe(postcss([autoprefixer({ |
||||||
|
browsers: [ |
||||||
|
'Chrome >= 35', |
||||||
|
'Firefox >= 38', |
||||||
|
'Edge >= 12', |
||||||
|
'Explorer >= 10', |
||||||
|
'iOS >= 8', |
||||||
|
'Safari >= 8', |
||||||
|
'Android 2.3', |
||||||
|
'Android >= 4', |
||||||
|
'Opera >= 12'] |
||||||
|
})])) |
||||||
|
.pipe(sourcemaps.write()) |
||||||
|
.pipe(gulp.dest(paths.scss.dest)) |
||||||
|
.pipe(cleanCss()) |
||||||
|
.pipe(rename({ suffix: '.min' })) |
||||||
|
.pipe(gulp.dest(paths.scss.dest)) |
||||||
|
.pipe(browserSync.stream()) |
||||||
|
} |
||||||
|
|
||||||
|
// Move the javascript files into our js folder
|
||||||
|
function js () { |
||||||
|
return gulp.src([paths.js.bootstrap, paths.js.jquery, paths.js.popper, paths.js.poppermap, paths.js.barrio]) |
||||||
|
.pipe(gulp.dest(paths.js.dest)) |
||||||
|
.pipe(browserSync.stream()) |
||||||
|
} |
||||||
|
|
||||||
|
// Static Server + watching scss/html files
|
||||||
|
function serve () { |
||||||
|
browserSync.init({ |
||||||
|
proxy: 'http://yourdomain.com', |
||||||
|
}) |
||||||
|
|
||||||
|
gulp.watch([paths.scss.watch, paths.scss.bootstrap], styles).on('change', browserSync.reload) |
||||||
|
} |
||||||
|
|
||||||
|
const build = gulp.series(styles, gulp.parallel(js, serve)) |
||||||
|
|
||||||
|
exports.styles = styles |
||||||
|
exports.js = js |
||||||
|
exports.serve = serve |
||||||
|
|
||||||
|
exports.default = build |
@ -0,0 +1,42 @@ |
|||||||
|
{ |
||||||
|
"name": "barrio_sass", |
||||||
|
"version": "4.4", |
||||||
|
"description": "Barrio SASS implementation", |
||||||
|
"main": "index.js", |
||||||
|
"scripts": { |
||||||
|
"test": "echo \"Error: no test specified\" && exit 1" |
||||||
|
}, |
||||||
|
"keywords": [ |
||||||
|
"SASS", |
||||||
|
"Bootstrap", |
||||||
|
"Drupal", |
||||||
|
"Barrio" |
||||||
|
], |
||||||
|
"author": "@hatuhay", |
||||||
|
"license": "MIT", |
||||||
|
"dependencies": { |
||||||
|
"bootstrap": "^4.4.1", |
||||||
|
"jquery": "^3.3.1", |
||||||
|
"popper.js": "^1.14.3", |
||||||
|
"bootstrap-icons": "^1.0.0-alpha3" |
||||||
|
}, |
||||||
|
"devDependencies": { |
||||||
|
"browser-sync": "^2.24.7", |
||||||
|
"del": "^3.0.0", |
||||||
|
"gulp": "^4.0.0", |
||||||
|
"gulp-autoprefixer": "^4.1.0", |
||||||
|
"gulp-scss-lint": "^1.0.0", |
||||||
|
"gulp-clean-css": "3.9.4", |
||||||
|
"gulp-concat": "^2.6.1", |
||||||
|
"gulp-html-replace": "^1.6.2", |
||||||
|
"gulp-rename": "^1.2.2", |
||||||
|
"gulp-sass": "^4.0.1", |
||||||
|
"gulp-sourcemaps": "^2.6.4", |
||||||
|
"gulp-postcss": "^8.0.0", |
||||||
|
"gulp-uglify": "^3.0.0", |
||||||
|
"merge-stream": "^1.0.1", |
||||||
|
"gulp-load-plugins": "^2.0.4", |
||||||
|
"postcss-inline-svg": "^4.1.0", |
||||||
|
"postcss-pxtorem": "^5.1.1" |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,40 @@ |
|||||||
|
name: biosafety |
||||||
|
type: theme |
||||||
|
description: 'SASS starter kit for a Bootstrap Barrio SubTheme.' |
||||||
|
# version: VERSION |
||||||
|
core: 8.x |
||||||
|
core_version_requirement: ^8 || ^9 || ^10 |
||||||
|
base theme: bootstrap_barrio |
||||||
|
|
||||||
|
libraries: |
||||||
|
- biosafety/global-styling |
||||||
|
libraries-override: |
||||||
|
bootstrap_barrio/global-styling: false |
||||||
|
regions: |
||||||
|
top_header: 'Top header' |
||||||
|
top_header_form: 'Top header form' |
||||||
|
header: Header |
||||||
|
header_form: 'Header form' |
||||||
|
primary_menu: 'Primary menu' |
||||||
|
secondary_menu: 'Secondary menu' |
||||||
|
page_top: 'Page top' |
||||||
|
page_bottom: 'Page bottom' |
||||||
|
highlighted: Highlighted |
||||||
|
featured_top: 'Featured top' |
||||||
|
breadcrumb: Breadcrumb |
||||||
|
content: Content |
||||||
|
sidebar_first: 'Sidebar first' |
||||||
|
sidebar_second: 'Sidebar second' |
||||||
|
featured_bottom_first: 'Featured bottom first' |
||||||
|
featured_bottom_second: 'Featured bottom second' |
||||||
|
featured_bottom_third: 'Featured bottom third' |
||||||
|
footer_first: 'Footer first' |
||||||
|
footer_second: 'Footer second' |
||||||
|
footer_third: 'Footer third' |
||||||
|
footer_fourth: 'Footer fourth' |
||||||
|
footer_fifth: 'Footer fifth' |
||||||
|
|
||||||
|
# Information added by Drupal.org packaging script on 2022-08-14 |
||||||
|
version: '5.0.6' |
||||||
|
project: 'biosafety' |
||||||
|
datestamp: 1660517237 |
@ -0,0 +1,14 @@ |
|||||||
|
global-styling: |
||||||
|
version: VERSION |
||||||
|
js: |
||||||
|
js/bootstrap.min.js: {} |
||||||
|
js/barrio.js: {} |
||||||
|
js/custom.js: {} |
||||||
|
css: |
||||||
|
component: |
||||||
|
css/style.css: {} |
||||||
|
dependencies: |
||||||
|
- core/jquery |
||||||
|
- core/jquery.once |
||||||
|
- core/drupal |
||||||
|
- core/popperjs |
@ -0,0 +1,32 @@ |
|||||||
|
<?php |
||||||
|
|
||||||
|
/** |
||||||
|
* @file |
||||||
|
* Functions to support theming in the SASS Starterkit subtheme. |
||||||
|
*/ |
||||||
|
|
||||||
|
use Drupal\Core\Form\FormStateInterface; |
||||||
|
|
||||||
|
/** |
||||||
|
* Implements hook_form_system_theme_settings_alter() for settings form. |
||||||
|
* |
||||||
|
* Replace Barrio setting options with subtheme ones. |
||||||
|
*/ |
||||||
|
function biosafety_form_system_theme_settings_alter(&$form, FormStateInterface $form_state) { |
||||||
|
$form['components']['navbar']['bootstrap_barrio_navbar_top_background']['#options'] = array( |
||||||
|
'bg-primary' => t('Primary'), |
||||||
|
'bg-secondary' => t('Secondary'), |
||||||
|
'bg-light' => t('Light'), |
||||||
|
'bg-dark' => t('Dark'), |
||||||
|
'bg-white' => t('White'), |
||||||
|
'bg-transparent' => t('Transparent'), |
||||||
|
); |
||||||
|
$form['components']['navbar']['bootstrap_barrio_navbar_background']['#options'] = array( |
||||||
|
'bg-primary' => t('Primary'), |
||||||
|
'bg-secondary' => t('Secondary'), |
||||||
|
'bg-light' => t('Light'), |
||||||
|
'bg-dark' => t('Dark'), |
||||||
|
'bg-white' => t('White'), |
||||||
|
'bg-transparent' => t('Transparent'), |
||||||
|
); |
||||||
|
} |
@ -0,0 +1,10 @@ |
|||||||
|
{ |
||||||
|
"name": "drupal/biosafety", |
||||||
|
"type": "drupal-theme", |
||||||
|
"description": "SASS subtheme for Barrio Theme.", |
||||||
|
"homepage": "http://drupal.org/project/biosafety", |
||||||
|
"license": "GPL-2.0+", |
||||||
|
"require": { |
||||||
|
"drupal/bootstrap_barrio": ">=5.1.3" |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,52 @@ |
|||||||
|
# Library. |
||||||
|
# ---------------------------- |
||||||
|
bootstrap_barrio_library: 'production' |
||||||
|
# Layout. |
||||||
|
# ---------------------------- |
||||||
|
bootstrap_barrio_sidebar_position: 'both' |
||||||
|
bootstrap_barrio_content_offset: 0 |
||||||
|
bootstrap_barrio_sidebar_first_width: 4 |
||||||
|
bootstrap_barrio_sidebar_first_offset: 0 |
||||||
|
bootstrap_barrio_sidebar_second_width: 3 |
||||||
|
bootstrap_barrio_sidebar_second_offset: 0 |
||||||
|
|
||||||
|
# Container. |
||||||
|
# ---------------------------- |
||||||
|
bootstrap_barrio_fluid_container: 0 |
||||||
|
|
||||||
|
# Buttons. |
||||||
|
# ---------------------------- |
||||||
|
bootstrap_barrio_button: 1 |
||||||
|
bootstrap_barrio_button_size: '' |
||||||
|
bootstrap_barrio_button_outline: 0 |
||||||
|
|
||||||
|
# Navbar. |
||||||
|
# ---------------------------- |
||||||
|
bootstrap_barrio_navbar_toggle: 'navbar-toggleable-lg' |
||||||
|
bootstrap_barrio_navbar_container: 'navbar-toggleable-md' |
||||||
|
bootstrap_barrio_navbar_top_position: '' |
||||||
|
bootstrap_barrio_navbar_top_color: 'navbar-dark' |
||||||
|
bootstrap_barrio_navbar_top_background: 'bg-secondary' |
||||||
|
bootstrap_barrio_navbar_position: '' |
||||||
|
bootstrap_barrio_navbar_color: 'navbar-dark' |
||||||
|
bootstrap_barrio_navbar_background: 'bg-primary' |
||||||
|
|
||||||
|
# Messages. |
||||||
|
# ---------------------------- |
||||||
|
bootstrap_barrio_messages_widget: 'toasts' |
||||||
|
|
||||||
|
# Form. |
||||||
|
# ---------------------------- |
||||||
|
bootstrap_barrio_radio: 'custom' |
||||||
|
bootstrap_barrio_checkbox: 'switch' |
||||||
|
bootstrap_barrio_select: 'custom' |
||||||
|
bootstrap_barrio_file: 'custom' |
||||||
|
|
||||||
|
# Colors. |
||||||
|
# ---------------------------- |
||||||
|
bootstrap_barrio_system_messages: 'messages_light' |
||||||
|
|
||||||
|
# Tables. |
||||||
|
# ---------------------------- |
||||||
|
bootstrap_barrio_table_hover: 1 |
||||||
|
bootstrap_barrio_table_style: 'table-striped' |
@ -0,0 +1,297 @@ |
|||||||
|
# Schema for the configuration files of the Bootstrap Barrio Subtheme. |
||||||
|
|
||||||
|
bootstrap_barrio_sass.settings: |
||||||
|
type: theme_settings |
||||||
|
label: 'Bootstrap Barrio settings' |
||||||
|
mapping: |
||||||
|
|
||||||
|
# Library. |
||||||
|
# ---------------------------- |
||||||
|
bootstrap_barrio_library: |
||||||
|
type: text |
||||||
|
label: 'Load library' |
||||||
|
|
||||||
|
# Container. |
||||||
|
# ---------------------------- |
||||||
|
bootstrap_barrio_fluid_container: |
||||||
|
type: integer |
||||||
|
label: 'Fluid container' |
||||||
|
|
||||||
|
# Region. |
||||||
|
# ---------------------------- |
||||||
|
bootstrap_barrio_region_clean_top_header: |
||||||
|
type: text |
||||||
|
label: 'Clean wrapper for Top header region' |
||||||
|
bootstrap_barrio_region_class_top_header: |
||||||
|
type: text |
||||||
|
label: 'Classes for Top header region' |
||||||
|
bootstrap_barrio_region_clean_top_header_form: |
||||||
|
type: text |
||||||
|
label: 'Clean wrapper for Top header form region' |
||||||
|
bootstrap_barrio_region_class_top_header_form: |
||||||
|
type: text |
||||||
|
label: 'Classes for Top header form region' |
||||||
|
bootstrap_barrio_region_clean_header: |
||||||
|
type: text |
||||||
|
label: 'Clean wrapper for Header region' |
||||||
|
bootstrap_barrio_region_class_header: |
||||||
|
type: text |
||||||
|
label: 'Classes for Header region' |
||||||
|
bootstrap_barrio_region_clean_header_form: |
||||||
|
type: text |
||||||
|
label: 'Clean wrapper for Header form region' |
||||||
|
bootstrap_barrio_region_class_header_form: |
||||||
|
type: text |
||||||
|
label: 'Classes for Header form region' |
||||||
|
bootstrap_barrio_region_clean_primary_menu: |
||||||
|
type: text |
||||||
|
label: 'Clean wrapper for Primary menu region' |
||||||
|
bootstrap_barrio_region_class_primary_menu: |
||||||
|
type: text |
||||||
|
label: 'Classes for Primary menu region' |
||||||
|
bootstrap_barrio_region_clean_secondary_menu: |
||||||
|
type: text |
||||||
|
label: 'Clean wrapper for Secondary menu region' |
||||||
|
bootstrap_barrio_region_class_secondary_menu: |
||||||
|
type: text |
||||||
|
label: 'Classes for Secondary menu region' |
||||||
|
bootstrap_barrio_region_clean_page_top: |
||||||
|
type: text |
||||||
|
label: 'Clean wrapper for Page top region' |
||||||
|
bootstrap_barrio_region_class_page_top: |
||||||
|
type: text |
||||||
|
label: 'Classes for Page top region' |
||||||
|
bootstrap_barrio_region_clean_page_bottom: |
||||||
|
type: text |
||||||
|
label: 'Clean wrapper for Page bottom region' |
||||||
|
bootstrap_barrio_region_class_page_bottom: |
||||||
|
type: text |
||||||
|
label: 'Classes for Page bottom region' |
||||||
|
bootstrap_barrio_region_clean_highlighted: |
||||||
|
type: text |
||||||
|
label: 'Clean wrapper for Highlighted region' |
||||||
|
bootstrap_barrio_region_class_highlighted: |
||||||
|
type: text |
||||||
|
label: 'Classes for Highlighted region' |
||||||
|
bootstrap_barrio_region_clean_featured_top: |
||||||
|
type: text |
||||||
|
label: 'Clean wrapper for Featured top region' |
||||||
|
bootstrap_barrio_region_class_featured_top: |
||||||
|
type: text |
||||||
|
label: 'Classes for Featured top region' |
||||||
|
bootstrap_barrio_region_clean_breadcrumb: |
||||||
|
type: text |
||||||
|
label: 'Clean wrapper for Breadcrumb region' |
||||||
|
bootstrap_barrio_region_class_breadcrumb: |
||||||
|
type: text |
||||||
|
label: 'Classes for Breadcrumb region' |
||||||
|
bootstrap_barrio_region_clean_content: |
||||||
|
type: text |
||||||
|
label: 'Clean wrapper for Content region' |
||||||
|
bootstrap_barrio_region_class_content: |
||||||
|
type: text |
||||||
|
label: 'Classes for Content region' |
||||||
|
bootstrap_barrio_region_clean_sidebar_first: |
||||||
|
type: text |
||||||
|
label: 'Clean wrapper for Sidebar first region' |
||||||
|
bootstrap_barrio_region_class_sidebar_first: |
||||||
|
type: text |
||||||
|
label: 'Classes for Sidebar first region' |
||||||
|
bootstrap_barrio_region_clean_sidebar_second: |
||||||
|
type: text |
||||||
|
label: 'Clean wrapper for Sidebar second region' |
||||||
|
bootstrap_barrio_region_class_sidebar_second: |
||||||
|
type: text |
||||||
|
label: 'Classes for Sidebar second region' |
||||||
|
bootstrap_barrio_region_clean_featured_bottom_first: |
||||||
|
type: text |
||||||
|
label: 'Clean wrapper for Featured bottom first region' |
||||||
|
bootstrap_barrio_region_class_featured_bottom_first: |
||||||
|
type: text |
||||||
|
label: 'Classes for Featured bottom first region' |
||||||
|
bootstrap_barrio_region_clean_featured_bottom_second: |
||||||
|
type: text |
||||||
|
label: 'Clean wrapper for Featured bottom second region' |
||||||
|
bootstrap_barrio_region_class_featured_bottom_second: |
||||||
|
type: text |
||||||
|
label: 'Classes for Featured bottom second region' |
||||||
|
bootstrap_barrio_region_clean_featured_bottom_third: |
||||||
|
type: text |
||||||
|
label: 'Clean wrapper for Featured bottom third region' |
||||||
|
bootstrap_barrio_region_class_featured_bottom_third: |
||||||
|
type: text |
||||||
|
label: 'Classes for Featured bottom third region' |
||||||
|
bootstrap_barrio_region_clean_footer_first: |
||||||
|
type: text |
||||||
|
label: 'Clean wrapper for Footer first region' |
||||||
|
bootstrap_barrio_region_class_footer_first: |
||||||
|
type: text |
||||||
|
label: 'Classes for Footer first region' |
||||||
|
bootstrap_barrio_region_clean_footer_second: |
||||||
|
type: text |
||||||
|
label: 'Clean wrapper for Footer second region' |
||||||
|
bootstrap_barrio_region_class_footer_second: |
||||||
|
type: text |
||||||
|
label: 'Classes for Footer second region' |
||||||
|
bootstrap_barrio_region_clean_footer_third: |
||||||
|
type: text |
||||||
|
label: 'Clean wrapper for Footer third region' |
||||||
|
bootstrap_barrio_region_class_footer_third: |
||||||
|
type: text |
||||||
|
label: 'Classes for Footer third region' |
||||||
|
bootstrap_barrio_region_clean_footer_fourth: |
||||||
|
type: text |
||||||
|
label: 'Clean wrapper for Footer fourth region' |
||||||
|
bootstrap_barrio_region_class_footer_fourth: |
||||||
|
type: text |
||||||
|
label: 'Classes for Footer fourth region' |
||||||
|
bootstrap_barrio_region_clean_footer_fifth: |
||||||
|
type: text |
||||||
|
label: 'Clean wrapper for Footer fifth region' |
||||||
|
bootstrap_barrio_region_class_footer_fifth: |
||||||
|
type: text |
||||||
|
label: 'Classes for Footer fifth region' |
||||||
|
|
||||||
|
# Sidebar position. |
||||||
|
# ---------------------------- |
||||||
|
bootstrap_barrio_sidebar_position: |
||||||
|
type: text |
||||||
|
label: 'Sidebar position' |
||||||
|
bootstrap_barrio_content_offset: |
||||||
|
type: integer |
||||||
|
label: 'Content offset' |
||||||
|
|
||||||
|
# Sidebar first layout. |
||||||
|
# ---------------------------- |
||||||
|
bootstrap_barrio_sidebar_collapse: |
||||||
|
type: integer |
||||||
|
label: 'Sidebar collapse' |
||||||
|
bootstrap_barrio_sidebar_first_width: |
||||||
|
type: integer |
||||||
|
label: 'Sidebar first width' |
||||||
|
bootstrap_barrio_sidebar_first_offset: |
||||||
|
type: integer |
||||||
|
label: 'Sidebar first offset' |
||||||
|
|
||||||
|
# Sidebar second layout. |
||||||
|
# ---------------------------- |
||||||
|
bootstrap_barrio_sidebar_second_width: |
||||||
|
type: integer |
||||||
|
label: 'Sidebar second width' |
||||||
|
bootstrap_barrio_sidebar_second_offset: |
||||||
|
type: integer |
||||||
|
label: 'Sidebar second layout' |
||||||
|
|
||||||
|
# Buttons. |
||||||
|
# ---------------------------- |
||||||
|
bootstrap_barrio_button: |
||||||
|
type: integer |
||||||
|
label: 'Convert input submit to button element' |
||||||
|
bootstrap_barrio_button_size: |
||||||
|
type: text |
||||||
|
label: 'Default button size' |
||||||
|
bootstrap_barrio_button_outline: |
||||||
|
type: integer |
||||||
|
label: 'Button with outline format' |
||||||
|
|
||||||
|
# Navbar. |
||||||
|
# ---------------------------- |
||||||
|
bootstrap_barrio_navbar_container: |
||||||
|
type: text |
||||||
|
label: 'Navbar width container' |
||||||
|
bootstrap_barrio_navbar_toggle: |
||||||
|
type: text |
||||||
|
label: 'Navbar toggle size' |
||||||
|
bootstrap_barrio_navbar_top_navbar: |
||||||
|
type: integer |
||||||
|
label: 'Navbar top is navbar' |
||||||
|
bootstrap_barrio_navbar_top_position: |
||||||
|
type: text |
||||||
|
label: 'Navbar top position' |
||||||
|
bootstrap_barrio_navbar_top_color: |
||||||
|
type: text |
||||||
|
label: 'Navbar top link color' |
||||||
|
bootstrap_barrio_navbar_top_background: |
||||||
|
type: text |
||||||
|
label: 'Navbar top background color' |
||||||
|
bootstrap_barrio_navbar_position: |
||||||
|
type: text |
||||||
|
label: 'Navbar position' |
||||||
|
bootstrap_barrio_navbar_color: |
||||||
|
type: text |
||||||
|
label: 'Navbar link color' |
||||||
|
bootstrap_barrio_navbar_background: |
||||||
|
type: text |
||||||
|
label: 'Navbar background color' |
||||||
|
|
||||||
|
# Messages. |
||||||
|
# ---------------------------- |
||||||
|
bootstrap_barrio_messages_widget: |
||||||
|
type: text |
||||||
|
label: 'Messages widget' |
||||||
|
|
||||||
|
# Form. |
||||||
|
# ---------------------------- |
||||||
|
bootstrap_barrio_radio: |
||||||
|
type: text |
||||||
|
label: 'Radio widget' |
||||||
|
bootstrap_barrio_checkbox: |
||||||
|
type: text |
||||||
|
label: 'Checkbox widget' |
||||||
|
bootstrap_barrio_select: |
||||||
|
type: text |
||||||
|
label: 'Select widget' |
||||||
|
bootstrap_barrio_file: |
||||||
|
type: text |
||||||
|
label: 'File widget' |
||||||
|
|
||||||
|
# Affix. |
||||||
|
# ---------------------------- |
||||||
|
bootstrap_barrio_navbar_top_affix: |
||||||
|
type: integer |
||||||
|
label: 'Affix navbar top' |
||||||
|
bootstrap_barrio_navbar_affix: |
||||||
|
type: integer |
||||||
|
label: 'Affix navbar' |
||||||
|
bootstrap_barrio_sidebar_first_affix: |
||||||
|
type: integer |
||||||
|
label: 'Affix sidebar first' |
||||||
|
bootstrap_barrio_sidebar_second_affix: |
||||||
|
type: integer |
||||||
|
label: 'Affix sidebar first' |
||||||
|
|
||||||
|
# Scrollspy. |
||||||
|
# ---------------------------- |
||||||
|
bootstrap_barrio_scroll_spy: |
||||||
|
type: text |
||||||
|
label: 'Scrollspy element ID' |
||||||
|
|
||||||
|
# Fonts. |
||||||
|
# ---------------------------- |
||||||
|
bootstrap_barrio_google_fonts: |
||||||
|
type: text |
||||||
|
label: 'Google Fonts combination' |
||||||
|
|
||||||
|
# Icons. |
||||||
|
# ---------------------------- |
||||||
|
bootstrap_barrio_icons: |
||||||
|
type: text |
||||||
|
label: 'Icon set' |
||||||
|
|
||||||
|
# System messages. |
||||||
|
# ---------------------------- |
||||||
|
bootstrap_barrio_system_messages: |
||||||
|
type: text |
||||||
|
label: 'System messages color scheme' |
||||||
|
|
||||||
|
# Tables. |
||||||
|
# ---------------------------- |
||||||
|
bootstrap_barrio_table_style: |
||||||
|
type: text |
||||||
|
label: 'Table cell style' |
||||||
|
bootstrap_barrio_table_hover: |
||||||
|
type: integer |
||||||
|
label: 'Hover effect over table cells' |
||||||
|
bootstrap_barrio_table_head: |
||||||
|
type: text |
||||||
|
label: 'Table header color scheme' |
@ -0,0 +1,91 @@ |
|||||||
|
let gulp = require('gulp'), |
||||||
|
sass = require('gulp-sass')(require('sass')), |
||||||
|
sourcemaps = require('gulp-sourcemaps'), |
||||||
|
$ = require('gulp-load-plugins')(), |
||||||
|
cleanCss = require('gulp-clean-css'), |
||||||
|
rename = require('gulp-rename'), |
||||||
|
postcss = require('gulp-postcss'), |
||||||
|
autoprefixer = require('autoprefixer'), |
||||||
|
postcssInlineSvg = require('postcss-inline-svg'), |
||||||
|
browserSync = require('browser-sync').create() |
||||||
|
pxtorem = require('postcss-pxtorem'), |
||||||
|
postcssProcessors = [ |
||||||
|
postcssInlineSvg({ |
||||||
|
removeFill: true, |
||||||
|
paths: ['./node_modules/bootstrap-icons/icons'] |
||||||
|
}), |
||||||
|
pxtorem({ |
||||||
|
propList: ['font', 'font-size', 'line-height', 'letter-spacing', '*margin*', '*padding*'], |
||||||
|
mediaQuery: true |
||||||
|
}) |
||||||
|
]; |
||||||
|
|
||||||
|
const paths = { |
||||||
|
scss: { |
||||||
|
src: './scss/style.scss', |
||||||
|
dest: './css', |
||||||
|
watch: './scss/**/*.scss', |
||||||
|
bootstrap: './node_modules/bootstrap/scss/bootstrap.scss', |
||||||
|
}, |
||||||
|
js: { |
||||||
|
bootstrap: './node_modules/bootstrap/dist/js/bootstrap.min.js', |
||||||
|
popper: './node_modules/@popperjs/core/dist/umd/popper.min.js', |
||||||
|
barrio: '../../contrib/bootstrap_barrio/js/barrio.js', |
||||||
|
dest: './js' |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// Compile sass into CSS & auto-inject into browsers
|
||||||
|
function styles () { |
||||||
|
return gulp.src([paths.scss.bootstrap, paths.scss.src]) |
||||||
|
.pipe(sourcemaps.init()) |
||||||
|
.pipe(sass({ |
||||||
|
includePaths: [ |
||||||
|
'./node_modules/bootstrap/scss', |
||||||
|
'../../contrib/bootstrap_barrio/scss' |
||||||
|
] |
||||||
|
}).on('error', sass.logError)) |
||||||
|
.pipe($.postcss(postcssProcessors)) |
||||||
|
.pipe(postcss([autoprefixer({ |
||||||
|
browsers: [ |
||||||
|
'Chrome >= 35', |
||||||
|
'Firefox >= 38', |
||||||
|
'Edge >= 12', |
||||||
|
'Explorer >= 10', |
||||||
|
'iOS >= 8', |
||||||
|
'Safari >= 8', |
||||||
|
'Android 2.3', |
||||||
|
'Android >= 4', |
||||||
|
'Opera >= 12'] |
||||||
|
})])) |
||||||
|
.pipe(sourcemaps.write()) |
||||||
|
.pipe(gulp.dest(paths.scss.dest)) |
||||||
|
.pipe(cleanCss()) |
||||||
|
.pipe(rename({ suffix: '.min' })) |
||||||
|
.pipe(gulp.dest(paths.scss.dest)) |
||||||
|
.pipe(browserSync.stream()) |
||||||
|
} |
||||||
|
|
||||||
|
// Move the javascript files into our js folder
|
||||||
|
function js () { |
||||||
|
return gulp.src([paths.js.bootstrap, paths.js.popper, paths.js.barrio]) |
||||||
|
.pipe(gulp.dest(paths.js.dest)) |
||||||
|
.pipe(browserSync.stream()) |
||||||
|
} |
||||||
|
|
||||||
|
// Static Server + watching scss/html files
|
||||||
|
function serve () { |
||||||
|
browserSync.init({ |
||||||
|
proxy: 'https://www.drupal.org', |
||||||
|
}) |
||||||
|
|
||||||
|
gulp.watch([paths.scss.watch, paths.scss.bootstrap], styles).on('change', browserSync.reload) |
||||||
|
} |
||||||
|
|
||||||
|
const build = gulp.series(styles, gulp.parallel(js, serve)) |
||||||
|
|
||||||
|
exports.styles = styles |
||||||
|
exports.js = js |
||||||
|
exports.serve = serve |
||||||
|
|
||||||
|
exports.default = build |
After Width: | Height: | Size: 94 B |
After Width: | Height: | Size: 294 B |
After Width: | Height: | Size: 189 B |
After Width: | Height: | Size: 346 B |
After Width: | Height: | Size: 189 B |
After Width: | Height: | Size: 314 B |
After Width: | Height: | Size: 1.7 KiB |
After Width: | Height: | Size: 385 B |
After Width: | Height: | Size: 260 B |
After Width: | Height: | Size: 265 B |
After Width: | Height: | Size: 220 B |
After Width: | Height: | Size: 220 B |
After Width: | Height: | Size: 276 B |
After Width: | Height: | Size: 214 B |
After Width: | Height: | Size: 196 B |
After Width: | Height: | Size: 181 B |
After Width: | Height: | Size: 183 B |
After Width: | Height: | Size: 83 B |
@ -0,0 +1,40 @@ |
|||||||
|
/** |
||||||
|
* @file |
||||||
|
* Global utilities. |
||||||
|
* |
||||||
|
*/ |
||||||
|
(function ($, Drupal) { |
||||||
|
|
||||||
|
'use strict'; |
||||||
|
|
||||||
|
Drupal.behaviors.bootstrap_barrio = { |
||||||
|
attach: function (context, settings) { |
||||||
|
|
||||||
|
var position = $(window).scrollTop(); |
||||||
|
$(window).scroll(function () { |
||||||
|
if ($(this).scrollTop() > 50) { |
||||||
|
$('body').addClass("scrolled"); |
||||||
|
} |
||||||
|
else { |
||||||
|
$('body').removeClass("scrolled"); |
||||||
|
} |
||||||
|
var scroll = $(window).scrollTop(); |
||||||
|
if (scroll > position) { |
||||||
|
$('body').addClass("scrolldown"); |
||||||
|
$('body').removeClass("scrollup"); |
||||||
|
} else { |
||||||
|
$('body').addClass("scrollup"); |
||||||
|
$('body').removeClass("scrolldown"); |
||||||
|
} |
||||||
|
position = scroll; |
||||||
|
}); |
||||||
|
|
||||||
|
$('.dropdown-item a.dropdown-toggle').on("click", function (e) { |
||||||
|
$(this).next('ul').toggle(); |
||||||
|
e.stopPropagation(); |
||||||
|
e.preventDefault(); |
||||||
|
}); |
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
})(jQuery, Drupal); |
@ -0,0 +1,18 @@ |
|||||||
|
/** |
||||||
|
* @file |
||||||
|
* Global utilities. |
||||||
|
* |
||||||
|
*/ |
||||||
|
(function($, Drupal) { |
||||||
|
|
||||||
|
'use strict'; |
||||||
|
|
||||||
|
Drupal.behaviors.biosafety = { |
||||||
|
attach: function(context, settings) { |
||||||
|
|
||||||
|
// Custom code here
|
||||||
|
|
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
})(jQuery, Drupal); |
After Width: | Height: | Size: 51 KiB |
@ -0,0 +1 @@ |
|||||||
|
../autoprefixer/bin/autoprefixer-info |
@ -0,0 +1 @@ |
|||||||
|
../browser-sync/dist/bin.js |
@ -0,0 +1 @@ |
|||||||
|
../browserslist/cli.js |
@ -0,0 +1 @@ |
|||||||
|
../color-support/bin.js |
@ -0,0 +1 @@ |
|||||||
|
../dev-ip/lib/dev-ip.js |
@ -0,0 +1 @@ |
|||||||
|
../esprima/bin/esparse.js |
@ -0,0 +1 @@ |
|||||||
|
../esprima/bin/esvalidate.js |
@ -0,0 +1 @@ |
|||||||
|
../js-yaml/bin/js-yaml.js |
@ -0,0 +1 @@ |
|||||||
|
../resolve/bin/resolve |
@ -0,0 +1 @@ |
|||||||
|
../stream-throttle/bin/throttleproxy.js |
@ -0,0 +1 @@ |
|||||||
|
../typescript/bin/tsserver |
@ -0,0 +1 @@ |
|||||||
|
../uglify-js/bin/uglifyjs |
@ -0,0 +1,21 @@ |
|||||||
|
The MIT License (MIT) |
||||||
|
|
||||||
|
Copyright (c) 2017 Blaine Bublitz <blaine.bublitz@gmail.com> |
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy |
||||||
|
of this software and associated documentation files (the "Software"), to deal |
||||||
|
in the Software without restriction, including without limitation the rights |
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
||||||
|
copies of the Software, and to permit persons to whom the Software is |
||||||
|
furnished to do so, subject to the following conditions: |
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all |
||||||
|
copies or substantial portions of the Software. |
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
||||||
|
SOFTWARE. |
@ -0,0 +1,40 @@ |
|||||||
|
# @gulp-sourcemaps/identity-map |
||||||
|
|
||||||
|
[![NPM version][npm-image]][npm-url] [![Downloads][downloads-image]][npm-url] [![Build Status][travis-image]][travis-url] [![AppVeyor Build Status][appveyor-image]][appveyor-url] [![Coveralls Status][coveralls-image]][coveralls-url] |
||||||
|
|
||||||
|
Gulp plugin for generating an identity sourcemap for a file. |
||||||
|
|
||||||
|
## Example |
||||||
|
|
||||||
|
```js |
||||||
|
var identityMap = require('@gulp-sourcemaps/identity-map'); |
||||||
|
|
||||||
|
gulp.src(...) |
||||||
|
.pipe(sourcemaps.init()) |
||||||
|
.pipe(identityMap()) // .js and .css files will get a generated sourcemap |
||||||
|
.pipe(sourcemaps.write()) |
||||||
|
.pipe(gulp.dest(...)) |
||||||
|
``` |
||||||
|
|
||||||
|
## API |
||||||
|
|
||||||
|
### `identityMap()` |
||||||
|
|
||||||
|
Returns an `objectMode` Transform stream that processes each file with a `.sourceMap` property and buffered contents. A sourcemap is generated and attached for each `.js` and `.css` file. |
||||||
|
|
||||||
|
## License |
||||||
|
|
||||||
|
MIT |
||||||
|
|
||||||
|
[downloads-image]: http://img.shields.io/npm/dm/@gulp-sourcemaps/identity-map.svg |
||||||
|
[npm-url]: https://npmjs.org/package/@gulp-sourcemaps/identity-map |
||||||
|
[npm-image]: http://img.shields.io/npm/v/@gulp-sourcemaps/identity-map.svg |
||||||
|
|
||||||
|
[travis-url]: https://travis-ci.org/gulp-sourcemaps/identity-map |
||||||
|
[travis-image]: http://img.shields.io/travis/gulp-sourcemaps/identity-map.svg?label=travis-ci |
||||||
|
|
||||||
|
[appveyor-url]: https://ci.appveyor.com/project/phated/identity-map |
||||||
|
[appveyor-image]: https://img.shields.io/appveyor/ci/phated/identity-map.svg?label=appveyor |
||||||
|
|
||||||
|
[coveralls-url]: https://coveralls.io/r/gulp-sourcemaps/identity-map |
||||||
|
[coveralls-image]: http://img.shields.io/coveralls/gulp-sourcemaps/identity-map.svg |
@ -0,0 +1,35 @@ |
|||||||
|
'use strict'; |
||||||
|
|
||||||
|
var through = require('through2'); |
||||||
|
var normalizePath = require('normalize-path'); |
||||||
|
|
||||||
|
var generate = require('./lib/generate'); |
||||||
|
|
||||||
|
function identityMap() { |
||||||
|
|
||||||
|
function transform(file, _, cb) { |
||||||
|
if (!file.sourceMap || !file.isBuffer()) { |
||||||
|
return cb(null, file); |
||||||
|
} |
||||||
|
|
||||||
|
var sourcePath = normalizePath(file.relative); |
||||||
|
var contents = file.contents.toString(); |
||||||
|
|
||||||
|
switch (file.extname) { |
||||||
|
case '.js': { |
||||||
|
file.sourceMap = generate.js(sourcePath, contents); |
||||||
|
break; |
||||||
|
} |
||||||
|
case '.css': { |
||||||
|
file.sourceMap = generate.css(sourcePath, contents); |
||||||
|
break; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
cb(null, file); |
||||||
|
} |
||||||
|
|
||||||
|
return through.obj(transform); |
||||||
|
} |
||||||
|
|
||||||
|
module.exports = identityMap; |
@ -0,0 +1,65 @@ |
|||||||
|
'use strict'; |
||||||
|
|
||||||
|
var css = require('css'); |
||||||
|
var acorn = require('acorn'); |
||||||
|
var SourceMapGenerator = require('source-map').SourceMapGenerator; |
||||||
|
|
||||||
|
function generateJs(sourcePath, fileContent) { |
||||||
|
var generator = new SourceMapGenerator({ file: sourcePath }); |
||||||
|
var tokenizer = acorn.tokenizer(fileContent, { allowHashBang: true, locations: true }); |
||||||
|
|
||||||
|
while (true) { |
||||||
|
var token = tokenizer.getToken(); |
||||||
|
|
||||||
|
if (token.type.label === 'eof') { |
||||||
|
break; |
||||||
|
} |
||||||
|
var mapping = { |
||||||
|
original: token.loc.start, |
||||||
|
generated: token.loc.start, |
||||||
|
source: sourcePath, |
||||||
|
}; |
||||||
|
if (token.type.label === 'name') { |
||||||
|
mapping.name = token.value; |
||||||
|
} |
||||||
|
generator.addMapping(mapping); |
||||||
|
} |
||||||
|
generator.setSourceContent(sourcePath, fileContent); |
||||||
|
|
||||||
|
return generator.toJSON(); |
||||||
|
} |
||||||
|
|
||||||
|
function generateCss(sourcePath, fileContent) { |
||||||
|
var generator = new SourceMapGenerator({ file: sourcePath }); |
||||||
|
var ast = css.parse(fileContent, { silent: true }); |
||||||
|
|
||||||
|
function registerTokens(ast) { |
||||||
|
if (ast.position) { |
||||||
|
generator.addMapping({ |
||||||
|
original: ast.position.start, |
||||||
|
generated: ast.position.start, |
||||||
|
source: sourcePath, |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
for (var key in ast) { |
||||||
|
if (key === 'position' || !ast[key]) { |
||||||
|
continue; |
||||||
|
} |
||||||
|
if (Object.prototype.toString.call(ast[key]) === '[object Object]') { |
||||||
|
registerTokens(ast[key]); |
||||||
|
} else if (Array.isArray(ast[key])) { |
||||||
|
ast[key].forEach(registerTokens); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
registerTokens(ast); |
||||||
|
generator.setSourceContent(sourcePath, fileContent); |
||||||
|
|
||||||
|
return generator.toJSON(); |
||||||
|
} |
||||||
|
|
||||||
|
module.exports = { |
||||||
|
js: generateJs, |
||||||
|
css: generateCss, |
||||||
|
}; |
@ -0,0 +1,21 @@ |
|||||||
|
The MIT License (MIT) |
||||||
|
|
||||||
|
Copyright (c) 2014-2017, Jon Schlinkert |
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy |
||||||
|
of this software and associated documentation files (the "Software"), to deal |
||||||
|
in the Software without restriction, including without limitation the rights |
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
||||||
|
copies of the Software, and to permit persons to whom the Software is |
||||||
|
furnished to do so, subject to the following conditions: |
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in |
||||||
|
all copies or substantial portions of the Software. |
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
||||||
|
THE SOFTWARE. |
@ -0,0 +1,92 @@ |
|||||||
|
# normalize-path [![NPM version](https://img.shields.io/npm/v/normalize-path.svg?style=flat)](https://www.npmjs.com/package/normalize-path) [![NPM monthly downloads](https://img.shields.io/npm/dm/normalize-path.svg?style=flat)](https://npmjs.org/package/normalize-path) [![NPM total downloads](https://img.shields.io/npm/dt/normalize-path.svg?style=flat)](https://npmjs.org/package/normalize-path) [![Linux Build Status](https://img.shields.io/travis/jonschlinkert/normalize-path.svg?style=flat&label=Travis)](https://travis-ci.org/jonschlinkert/normalize-path) |
||||||
|
|
||||||
|
> Normalize file path slashes to be unix-like forward slashes. Also condenses repeat slashes to a single slash and removes and trailing slashes unless disabled. |
||||||
|
|
||||||
|
## Install |
||||||
|
|
||||||
|
Install with [npm](https://www.npmjs.com/): |
||||||
|
|
||||||
|
```sh |
||||||
|
$ npm install --save normalize-path |
||||||
|
``` |
||||||
|
|
||||||
|
## Usage |
||||||
|
|
||||||
|
```js |
||||||
|
var normalize = require('normalize-path'); |
||||||
|
|
||||||
|
normalize('\\foo\\bar\\baz\\'); |
||||||
|
//=> '/foo/bar/baz' |
||||||
|
|
||||||
|
normalize('./foo/bar/baz/'); |
||||||
|
//=> './foo/bar/baz' |
||||||
|
``` |
||||||
|
|
||||||
|
Pass `false` as the last argument to **keep** trailing slashes: |
||||||
|
|
||||||
|
```js |
||||||
|
normalize('./foo/bar/baz/', false); |
||||||
|
//=> './foo/bar/baz/' |
||||||
|
|
||||||
|
normalize('foo\\bar\\baz\\', false); |
||||||
|
//=> 'foo/bar/baz/' |
||||||
|
``` |
||||||
|
|
||||||
|
## About |
||||||
|
|
||||||
|
### Related projects |
||||||
|
|
||||||
|
* [contains-path](https://www.npmjs.com/package/contains-path): Return true if a file path contains the given path. | [homepage](https://github.com/jonschlinkert/contains-path "Return true if a file path contains the given path.") |
||||||
|
* [ends-with](https://www.npmjs.com/package/ends-with): Returns `true` if the given `string` or `array` ends with `suffix` using strict equality for… [more](https://github.com/jonschlinkert/ends-with) | [homepage](https://github.com/jonschlinkert/ends-with "Returns `true` if the given `string` or `array` ends with `suffix` using strict equality for comparisons.") |
||||||
|
* [is-absolute](https://www.npmjs.com/package/is-absolute): Polyfill for node.js `path.isAbolute`. Returns true if a file path is absolute. | [homepage](https://github.com/jonschlinkert/is-absolute "Polyfill for node.js `path.isAbolute`. Returns true if a file path is absolute.") |
||||||
|
* [is-relative](https://www.npmjs.com/package/is-relative): Returns `true` if the path appears to be relative. | [homepage](https://github.com/jonschlinkert/is-relative "Returns `true` if the path appears to be relative.") |
||||||
|
* [parse-filepath](https://www.npmjs.com/package/parse-filepath): Pollyfill for node.js `path.parse`, parses a filepath into an object. | [homepage](https://github.com/jonschlinkert/parse-filepath "Pollyfill for node.js `path.parse`, parses a filepath into an object.") |
||||||
|
* [path-ends-with](https://www.npmjs.com/package/path-ends-with): Return `true` if a file path ends with the given string/suffix. | [homepage](https://github.com/jonschlinkert/path-ends-with "Return `true` if a file path ends with the given string/suffix.") |
||||||
|
* [path-segments](https://www.npmjs.com/package/path-segments): Get n specific segments of a file path, e.g. first 2, last 3, etc. | [homepage](https://github.com/jonschlinkert/path-segments "Get n specific segments of a file path, e.g. first 2, last 3, etc.") |
||||||
|
* [rewrite-ext](https://www.npmjs.com/package/rewrite-ext): Automatically re-write the destination extension of a filepath based on the source extension. e.g… [more](https://github.com/jonschlinkert/rewrite-ext) | [homepage](https://github.com/jonschlinkert/rewrite-ext "Automatically re-write the destination extension of a filepath based on the source extension. e.g `.coffee` => `.js`. This will only rename the ext, no other path parts are modified.") |
||||||
|
* [unixify](https://www.npmjs.com/package/unixify): Convert Windows file paths to unix paths. | [homepage](https://github.com/jonschlinkert/unixify "Convert Windows file paths to unix paths.") |
||||||
|
|
||||||
|
### Contributing |
||||||
|
|
||||||
|
Pull requests and stars are always welcome. For bugs and feature requests, [please create an issue](../../issues/new). |
||||||
|
|
||||||
|
### Contributors |
||||||
|
|
||||||
|
| **Commits** | **Contributor** | |
||||||
|
| --- | --- | |
||||||
|
| 31 | [jonschlinkert](https://github.com/jonschlinkert) | |
||||||
|
| 1 | [phated](https://github.com/phated) | |
||||||
|
|
||||||
|
### Building docs |
||||||
|
|
||||||
|
_(This project's readme.md is generated by [verb](https://github.com/verbose/verb-generate-readme), please don't edit the readme directly. Any changes to the readme must be made in the [.verb.md](.verb.md) readme template.)_ |
||||||
|
|
||||||
|
To generate the readme, run the following command: |
||||||
|
|
||||||
|
```sh |
||||||
|
$ npm install -g verbose/verb#dev verb-generate-readme && verb |
||||||
|
``` |
||||||
|
|
||||||
|
### Running tests |
||||||
|
|
||||||
|
Running and reviewing unit tests is a great way to get familiarized with a library and its API. You can install dependencies and run tests with the following command: |
||||||
|
|
||||||
|
```sh |
||||||
|
$ npm install && npm test |
||||||
|
``` |
||||||
|
|
||||||
|
### Author |
||||||
|
|
||||||
|
**Jon Schlinkert** |
||||||
|
|
||||||
|
* [github/jonschlinkert](https://github.com/jonschlinkert) |
||||||
|
* [twitter/jonschlinkert](https://twitter.com/jonschlinkert) |
||||||
|
|
||||||
|
### License |
||||||
|
|
||||||
|
Copyright © 2017, [Jon Schlinkert](https://github.com/jonschlinkert). |
||||||
|
Released under the [MIT License](LICENSE). |
||||||
|
|
||||||
|
*** |
||||||
|
|
||||||
|
_This file was generated by [verb-generate-readme](https://github.com/verbose/verb-generate-readme), v0.4.3, on March 29, 2017._ |
@ -0,0 +1,19 @@ |
|||||||
|
/*! |
||||||
|
* normalize-path <https://github.com/jonschlinkert/normalize-path>
|
||||||
|
* |
||||||
|
* Copyright (c) 2014-2017, Jon Schlinkert. |
||||||
|
* Released under the MIT License. |
||||||
|
*/ |
||||||
|
|
||||||
|
var removeTrailingSeparator = require('remove-trailing-separator'); |
||||||
|
|
||||||
|
module.exports = function normalizePath(str, stripTrailing) { |
||||||
|
if (typeof str !== 'string') { |
||||||
|
throw new TypeError('expected a string'); |
||||||
|
} |
||||||
|
str = str.replace(/[\\\/]+/g, '/'); |
||||||
|
if (stripTrailing !== false) { |
||||||
|
str = removeTrailingSeparator(str); |
||||||
|
} |
||||||
|
return str; |
||||||
|
}; |
@ -0,0 +1,78 @@ |
|||||||
|
{ |
||||||
|
"name": "normalize-path", |
||||||
|
"description": "Normalize file path slashes to be unix-like forward slashes. Also condenses repeat slashes to a single slash and removes and trailing slashes unless disabled.", |
||||||
|
"version": "2.1.1", |
||||||
|
"homepage": "https://github.com/jonschlinkert/normalize-path", |
||||||
|
"author": "Jon Schlinkert (https://github.com/jonschlinkert)", |
||||||
|
"contributors": [ |
||||||
|
"Blaine Bublitz <blaine.bublitz@gmail.com> (https://twitter.com/BlaineBublitz)", |
||||||
|
"Jon Schlinkert <jon.schlinkert@sellside.com> (http://twitter.com/jonschlinkert)" |
||||||
|
], |
||||||
|
"repository": "jonschlinkert/normalize-path", |
||||||
|
"bugs": { |
||||||
|
"url": "https://github.com/jonschlinkert/normalize-path/issues" |
||||||
|
}, |
||||||
|
"license": "MIT", |
||||||
|
"files": [ |
||||||
|
"index.js" |
||||||
|
], |
||||||
|
"main": "index.js", |
||||||
|
"engines": { |
||||||
|
"node": ">=0.10.0" |
||||||
|
}, |
||||||
|
"scripts": { |
||||||
|
"test": "mocha" |
||||||
|
}, |
||||||
|
"dependencies": { |
||||||
|
"remove-trailing-separator": "^1.0.1" |
||||||
|
}, |
||||||
|
"devDependencies": { |
||||||
|
"benchmarked": "^0.1.1", |
||||||
|
"gulp-format-md": "^0.1.11", |
||||||
|
"minimist": "^1.2.0", |
||||||
|
"mocha": "*" |
||||||
|
}, |
||||||
|
"keywords": [ |
||||||
|
"backslash", |
||||||
|
"file", |
||||||
|
"filepath", |
||||||
|
"fix", |
||||||
|
"forward", |
||||||
|
"fp", |
||||||
|
"fs", |
||||||
|
"normalize", |
||||||
|
"path", |
||||||
|
"slash", |
||||||
|
"slashes", |
||||||
|
"trailing", |
||||||
|
"unix", |
||||||
|
"urix" |
||||||
|
], |
||||||
|
"verb": { |
||||||
|
"related": { |
||||||
|
"list": [ |
||||||
|
"contains-path", |
||||||
|
"ends-with", |
||||||
|
"is-absolute", |
||||||
|
"is-relative", |
||||||
|
"parse-filepath", |
||||||
|
"path-ends-with", |
||||||
|
"path-segments", |
||||||
|
"rewrite-ext", |
||||||
|
"unixify" |
||||||
|
], |
||||||
|
"description": "Other useful libraries for working with paths in node.js:" |
||||||
|
}, |
||||||
|
"toc": false, |
||||||
|
"layout": "default", |
||||||
|
"tasks": [ |
||||||
|
"readme" |
||||||
|
], |
||||||
|
"plugins": [ |
||||||
|
"gulp-format-md" |
||||||
|
], |
||||||
|
"lint": { |
||||||
|
"reflinks": true |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,301 @@ |
|||||||
|
# Change Log |
||||||
|
|
||||||
|
## 0.5.6 |
||||||
|
|
||||||
|
* Fix for regression when people were using numbers as names in source maps. See |
||||||
|
#236. |
||||||
|
|
||||||
|
## 0.5.5 |
||||||
|
|
||||||
|
* Fix "regression" of unsupported, implementation behavior that half the world |
||||||
|
happens to have come to depend on. See #235. |
||||||
|
|
||||||
|
* Fix regression involving function hoisting in SpiderMonkey. See #233. |
||||||
|
|
||||||
|
## 0.5.4 |
||||||
|
|
||||||
|
* Large performance improvements to source-map serialization. See #228 and #229. |
||||||
|
|
||||||
|
## 0.5.3 |
||||||
|
|
||||||
|
* Do not include unnecessary distribution files. See |
||||||
|
commit ef7006f8d1647e0a83fdc60f04f5a7ca54886f86. |
||||||
|
|
||||||
|
## 0.5.2 |
||||||
|
|
||||||
|
* Include browser distributions of the library in package.json's `files`. See |
||||||
|
issue #212. |
||||||
|
|
||||||
|
## 0.5.1 |
||||||
|
|
||||||
|
* Fix latent bugs in IndexedSourceMapConsumer.prototype._parseMappings. See |
||||||
|
ff05274becc9e6e1295ed60f3ea090d31d843379. |
||||||
|
|
||||||
|
## 0.5.0 |
||||||
|
|
||||||
|
* Node 0.8 is no longer supported. |
||||||
|
|
||||||
|
* Use webpack instead of dryice for bundling. |
||||||
|
|
||||||
|
* Big speedups serializing source maps. See pull request #203. |
||||||
|
|
||||||
|
* Fix a bug with `SourceMapConsumer.prototype.sourceContentFor` and sources that |
||||||
|
explicitly start with the source root. See issue #199. |
||||||
|
|
||||||
|
## 0.4.4 |
||||||
|
|
||||||
|
* Fix an issue where using a `SourceMapGenerator` after having created a |
||||||
|
`SourceMapConsumer` from it via `SourceMapConsumer.fromSourceMap` failed. See |
||||||
|
issue #191. |
||||||
|
|
||||||
|
* Fix an issue with where `SourceMapGenerator` would mistakenly consider |
||||||
|
different mappings as duplicates of each other and avoid generating them. See |
||||||
|
issue #192. |
||||||
|
|
||||||
|
## 0.4.3 |
||||||
|
|
||||||
|
* A very large number of performance improvements, particularly when parsing |
||||||
|
source maps. Collectively about 75% of time shaved off of the source map |
||||||
|
parsing benchmark! |
||||||
|
|
||||||
|
* Fix a bug in `SourceMapConsumer.prototype.allGeneratedPositionsFor` and fuzzy |
||||||
|
searching in the presence of a column option. See issue #177. |
||||||
|
|
||||||
|
* Fix a bug with joining a source and its source root when the source is above |
||||||
|
the root. See issue #182. |
||||||
|
|
||||||
|
* Add the `SourceMapConsumer.prototype.hasContentsOfAllSources` method to |
||||||
|
determine when all sources' contents are inlined into the source map. See |
||||||
|
issue #190. |
||||||
|
|
||||||
|
## 0.4.2 |
||||||
|
|
||||||
|
* Add an `.npmignore` file so that the benchmarks aren't pulled down by |
||||||
|
dependent projects. Issue #169. |
||||||
|
|
||||||
|
* Add an optional `column` argument to |
||||||
|
`SourceMapConsumer.prototype.allGeneratedPositionsFor` and better handle lines |
||||||
|
with no mappings. Issues #172 and #173. |
||||||
|
|
||||||
|
## 0.4.1 |
||||||
|
|
||||||
|
* Fix accidentally defining a global variable. #170. |
||||||
|
|
||||||
|
## 0.4.0 |
||||||
|
|
||||||
|
* The default direction for fuzzy searching was changed back to its original |
||||||
|
direction. See #164. |
||||||
|
|
||||||
|
* There is now a `bias` option you can supply to `SourceMapConsumer` to control |
||||||
|
the fuzzy searching direction. See #167. |
||||||
|
|
||||||
|
* About an 8% speed up in parsing source maps. See #159. |
||||||
|
|
||||||
|
* Added a benchmark for parsing and generating source maps. |
||||||
|
|
||||||
|
## 0.3.0 |
||||||
|
|
||||||
|
* Change the default direction that searching for positions fuzzes when there is |
||||||
|
not an exact match. See #154. |
||||||
|
|
||||||
|
* Support for environments using json2.js for JSON serialization. See #156. |
||||||
|
|
||||||
|
## 0.2.0 |
||||||
|
|
||||||
|
* Support for consuming "indexed" source maps which do not have any remote |
||||||
|
sections. See pull request #127. This introduces a minor backwards |
||||||
|
incompatibility if you are monkey patching `SourceMapConsumer.prototype` |
||||||
|
methods. |
||||||
|
|
||||||
|
## 0.1.43 |
||||||
|
|
||||||
|
* Performance improvements for `SourceMapGenerator` and `SourceNode`. See issue |
||||||
|
#148 for some discussion and issues #150, #151, and #152 for implementations. |
||||||
|
|
||||||
|
## 0.1.42 |
||||||
|
|
||||||
|
* Fix an issue where `SourceNode`s from different versions of the source-map |
||||||
|
library couldn't be used in conjunction with each other. See issue #142. |
||||||
|
|
||||||
|
## 0.1.41 |
||||||
|
|
||||||
|
* Fix a bug with getting the source content of relative sources with a "./" |
||||||
|
prefix. See issue #145 and [Bug 1090768](bugzil.la/1090768). |
||||||
|
|
||||||
|
* Add the `SourceMapConsumer.prototype.computeColumnSpans` method to compute the |
||||||
|
column span of each mapping. |
||||||
|
|
||||||
|
* Add the `SourceMapConsumer.prototype.allGeneratedPositionsFor` method to find |
||||||
|
all generated positions associated with a given original source and line. |
||||||
|
|
||||||
|
## 0.1.40 |
||||||
|
|
||||||
|
* Performance improvements for parsing source maps in SourceMapConsumer. |
||||||
|
|
||||||
|
## 0.1.39 |
||||||
|
|
||||||
|
* Fix a bug where setting a source's contents to null before any source content |
||||||
|
had been set before threw a TypeError. See issue #131. |
||||||
|
|
||||||
|
## 0.1.38 |
||||||
|
|
||||||
|
* Fix a bug where finding relative paths from an empty path were creating |
||||||
|
absolute paths. See issue #129. |
||||||
|
|
||||||
|
## 0.1.37 |
||||||
|
|
||||||
|
* Fix a bug where if the source root was an empty string, relative source paths |
||||||
|
would turn into absolute source paths. Issue #124. |
||||||
|
|
||||||
|
## 0.1.36 |
||||||
|
|
||||||
|
* Allow the `names` mapping property to be an empty string. Issue #121. |
||||||
|
|
||||||
|
## 0.1.35 |
||||||
|
|
||||||
|
* A third optional parameter was added to `SourceNode.fromStringWithSourceMap` |
||||||
|
to specify a path that relative sources in the second parameter should be |
||||||
|
relative to. Issue #105. |
||||||
|
|
||||||
|
* If no file property is given to a `SourceMapGenerator`, then the resulting |
||||||
|
source map will no longer have a `null` file property. The property will |
||||||
|
simply not exist. Issue #104. |
||||||
|
|
||||||
|
* Fixed a bug where consecutive newlines were ignored in `SourceNode`s. |
||||||
|
Issue #116. |
||||||
|
|
||||||
|
## 0.1.34 |
||||||
|
|
||||||
|
* Make `SourceNode` work with windows style ("\r\n") newlines. Issue #103. |
||||||
|
|
||||||
|
* Fix bug involving source contents and the |
||||||
|
`SourceMapGenerator.prototype.applySourceMap`. Issue #100. |
||||||
|
|
||||||
|
## 0.1.33 |
||||||
|
|
||||||
|
* Fix some edge cases surrounding path joining and URL resolution. |
||||||
|
|
||||||
|
* Add a third parameter for relative path to |
||||||
|
`SourceMapGenerator.prototype.applySourceMap`. |
||||||
|
|
||||||
|
* Fix issues with mappings and EOLs. |
||||||
|
|
||||||
|
## 0.1.32 |
||||||
|
|
||||||
|
* Fixed a bug where SourceMapConsumer couldn't handle negative relative columns |
||||||
|
(issue 92). |
||||||
|
|
||||||
|
* Fixed test runner to actually report number of failed tests as its process |
||||||
|
exit code. |
||||||
|
|
||||||
|
* Fixed a typo when reporting bad mappings (issue 87). |
||||||
|
|
||||||
|
## 0.1.31 |
||||||
|
|
||||||
|
* Delay parsing the mappings in SourceMapConsumer until queried for a source |
||||||
|
location. |
||||||
|
|
||||||
|
* Support Sass source maps (which at the time of writing deviate from the spec |
||||||
|
in small ways) in SourceMapConsumer. |
||||||
|
|
||||||
|
## 0.1.30 |
||||||
|
|
||||||
|
* Do not join source root with a source, when the source is a data URI. |
||||||
|
|
||||||
|
* Extend the test runner to allow running single specific test files at a time. |
||||||
|
|
||||||
|
* Performance improvements in `SourceNode.prototype.walk` and |
||||||
|
`SourceMapConsumer.prototype.eachMapping`. |
||||||
|
|
||||||
|
* Source map browser builds will now work inside Workers. |
||||||
|
|
||||||
|
* Better error messages when attempting to add an invalid mapping to a |
||||||
|
`SourceMapGenerator`. |
||||||
|
|
||||||
|
## 0.1.29 |
||||||
|
|
||||||
|
* Allow duplicate entries in the `names` and `sources` arrays of source maps |
||||||
|
(usually from TypeScript) we are parsing. Fixes github issue 72. |
||||||
|
|
||||||
|
## 0.1.28 |
||||||
|
|
||||||
|
* Skip duplicate mappings when creating source maps from SourceNode; github |
||||||
|
issue 75. |
||||||
|
|
||||||
|
## 0.1.27 |
||||||
|
|
||||||
|
* Don't throw an error when the `file` property is missing in SourceMapConsumer, |
||||||
|
we don't use it anyway. |
||||||
|
|
||||||
|
## 0.1.26 |
||||||
|
|
||||||
|
* Fix SourceNode.fromStringWithSourceMap for empty maps. Fixes github issue 70. |
||||||
|
|
||||||
|
## 0.1.25 |
||||||
|
|
||||||
|
* Make compatible with browserify |
||||||
|
|
||||||
|
## 0.1.24 |
||||||
|
|
||||||
|
* Fix issue with absolute paths and `file://` URIs. See |
||||||
|
https://bugzilla.mozilla.org/show_bug.cgi?id=885597 |
||||||
|
|
||||||
|
## 0.1.23 |
||||||
|
|
||||||
|
* Fix issue with absolute paths and sourcesContent, github issue 64. |
||||||
|
|
||||||
|
## 0.1.22 |
||||||
|
|
||||||
|
* Ignore duplicate mappings in SourceMapGenerator. Fixes github issue 21. |
||||||
|
|
||||||
|
## 0.1.21 |
||||||
|
|
||||||
|
* Fixed handling of sources that start with a slash so that they are relative to |
||||||
|
the source root's host. |
||||||
|
|
||||||
|
## 0.1.20 |
||||||
|
|
||||||
|
* Fixed github issue #43: absolute URLs aren't joined with the source root |
||||||
|
anymore. |
||||||
|
|
||||||
|
## 0.1.19 |
||||||
|
|
||||||
|
* Using Travis CI to run tests. |
||||||
|
|
||||||
|
## 0.1.18 |
||||||
|
|
||||||
|
* Fixed a bug in the handling of sourceRoot. |
||||||
|
|
||||||
|
## 0.1.17 |
||||||
|
|
||||||
|
* Added SourceNode.fromStringWithSourceMap. |
||||||
|
|
||||||
|
## 0.1.16 |
||||||
|
|
||||||
|
* Added missing documentation. |
||||||
|
|
||||||
|
* Fixed the generating of empty mappings in SourceNode. |
||||||
|
|
||||||
|
## 0.1.15 |
||||||
|
|
||||||
|
* Added SourceMapGenerator.applySourceMap. |
||||||
|
|
||||||
|
## 0.1.14 |
||||||
|
|
||||||
|
* The sourceRoot is now handled consistently. |
||||||
|
|
||||||
|
## 0.1.13 |
||||||
|
|
||||||
|
* Added SourceMapGenerator.fromSourceMap. |
||||||
|
|
||||||
|
## 0.1.12 |
||||||
|
|
||||||
|
* SourceNode now generates empty mappings too. |
||||||
|
|
||||||
|
## 0.1.11 |
||||||
|
|
||||||
|
* Added name support to SourceNode. |
||||||
|
|
||||||
|
## 0.1.10 |
||||||
|
|
||||||
|
* Added sourcesContent support to the customer and generator. |
@ -0,0 +1,28 @@ |
|||||||
|
|
||||||
|
Copyright (c) 2009-2011, Mozilla Foundation and contributors |
||||||
|
All rights reserved. |
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without |
||||||
|
modification, are permitted provided that the following conditions are met: |
||||||
|
|
||||||
|
* Redistributions of source code must retain the above copyright notice, this |
||||||
|
list of conditions and the following disclaimer. |
||||||
|
|
||||||
|
* Redistributions in binary form must reproduce the above copyright notice, |
||||||
|
this list of conditions and the following disclaimer in the documentation |
||||||
|
and/or other materials provided with the distribution. |
||||||
|
|
||||||
|
* Neither the names of the Mozilla Foundation nor the names of project |
||||||
|
contributors may be used to endorse or promote products derived from this |
||||||
|
software without specific prior written permission. |
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND |
||||||
|
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
||||||
|
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
||||||
|
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE |
||||||
|
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
||||||
|
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR |
||||||
|
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER |
||||||
|
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, |
||||||
|
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
@ -0,0 +1,742 @@ |
|||||||
|
# Source Map |
||||||
|
|
||||||
|
[![Build Status](https://travis-ci.org/mozilla/source-map.png?branch=master)](https://travis-ci.org/mozilla/source-map) |
||||||
|
|
||||||
|
[![NPM](https://nodei.co/npm/source-map.png?downloads=true&downloadRank=true)](https://www.npmjs.com/package/source-map) |
||||||
|
|
||||||
|
This is a library to generate and consume the source map format |
||||||
|
[described here][format]. |
||||||
|
|
||||||
|
[format]: https://docs.google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k/edit |
||||||
|
|
||||||
|
## Use with Node |
||||||
|
|
||||||
|
$ npm install source-map |
||||||
|
|
||||||
|
## Use on the Web |
||||||
|
|
||||||
|
<script src="https://raw.githubusercontent.com/mozilla/source-map/master/dist/source-map.min.js" defer></script> |
||||||
|
|
||||||
|
-------------------------------------------------------------------------------- |
||||||
|
|
||||||
|
<!-- `npm run toc` to regenerate the Table of Contents --> |
||||||
|
|
||||||
|
<!-- START doctoc generated TOC please keep comment here to allow auto update --> |
||||||
|
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE --> |
||||||
|
## Table of Contents |
||||||
|
|
||||||
|
- [Examples](#examples) |
||||||
|
- [Consuming a source map](#consuming-a-source-map) |
||||||
|
- [Generating a source map](#generating-a-source-map) |
||||||
|
- [With SourceNode (high level API)](#with-sourcenode-high-level-api) |
||||||
|
- [With SourceMapGenerator (low level API)](#with-sourcemapgenerator-low-level-api) |
||||||
|
- [API](#api) |
||||||
|
- [SourceMapConsumer](#sourcemapconsumer) |
||||||
|
- [new SourceMapConsumer(rawSourceMap)](#new-sourcemapconsumerrawsourcemap) |
||||||
|
- [SourceMapConsumer.prototype.computeColumnSpans()](#sourcemapconsumerprototypecomputecolumnspans) |
||||||
|
- [SourceMapConsumer.prototype.originalPositionFor(generatedPosition)](#sourcemapconsumerprototypeoriginalpositionforgeneratedposition) |
||||||
|
- [SourceMapConsumer.prototype.generatedPositionFor(originalPosition)](#sourcemapconsumerprototypegeneratedpositionfororiginalposition) |
||||||
|
- [SourceMapConsumer.prototype.allGeneratedPositionsFor(originalPosition)](#sourcemapconsumerprototypeallgeneratedpositionsfororiginalposition) |
||||||
|
- [SourceMapConsumer.prototype.hasContentsOfAllSources()](#sourcemapconsumerprototypehascontentsofallsources) |
||||||
|
- [SourceMapConsumer.prototype.sourceContentFor(source[, returnNullOnMissing])](#sourcemapconsumerprototypesourcecontentforsource-returnnullonmissing) |
||||||
|
- [SourceMapConsumer.prototype.eachMapping(callback, context, order)](#sourcemapconsumerprototypeeachmappingcallback-context-order) |
||||||
|
- [SourceMapGenerator](#sourcemapgenerator) |
||||||
|
- [new SourceMapGenerator([startOfSourceMap])](#new-sourcemapgeneratorstartofsourcemap) |
||||||
|
- [SourceMapGenerator.fromSourceMap(sourceMapConsumer)](#sourcemapgeneratorfromsourcemapsourcemapconsumer) |
||||||
|
- [SourceMapGenerator.prototype.addMapping(mapping)](#sourcemapgeneratorprototypeaddmappingmapping) |
||||||
|
- [SourceMapGenerator.prototype.setSourceContent(sourceFile, sourceContent)](#sourcemapgeneratorprototypesetsourcecontentsourcefile-sourcecontent) |
||||||
|
- [SourceMapGenerator.prototype.applySourceMap(sourceMapConsumer[, sourceFile[, sourceMapPath]])](#sourcemapgeneratorprototypeapplysourcemapsourcemapconsumer-sourcefile-sourcemappath) |
||||||
|
- [SourceMapGenerator.prototype.toString()](#sourcemapgeneratorprototypetostring) |
||||||
|
- [SourceNode](#sourcenode) |
||||||
|
- [new SourceNode([line, column, source[, chunk[, name]]])](#new-sourcenodeline-column-source-chunk-name) |
||||||
|
- [SourceNode.fromStringWithSourceMap(code, sourceMapConsumer[, relativePath])](#sourcenodefromstringwithsourcemapcode-sourcemapconsumer-relativepath) |
||||||
|
- [SourceNode.prototype.add(chunk)](#sourcenodeprototypeaddchunk) |
||||||
|
- [SourceNode.prototype.prepend(chunk)](#sourcenodeprototypeprependchunk) |
||||||
|
- [SourceNode.prototype.setSourceContent(sourceFile, sourceContent)](#sourcenodeprototypesetsourcecontentsourcefile-sourcecontent) |
||||||
|
- [SourceNode.prototype.walk(fn)](#sourcenodeprototypewalkfn) |
||||||
|
- [SourceNode.prototype.walkSourceContents(fn)](#sourcenodeprototypewalksourcecontentsfn) |
||||||
|
- [SourceNode.prototype.join(sep)](#sourcenodeprototypejoinsep) |
||||||
|
- [SourceNode.prototype.replaceRight(pattern, replacement)](#sourcenodeprototypereplacerightpattern-replacement) |
||||||
|
- [SourceNode.prototype.toString()](#sourcenodeprototypetostring) |
||||||
|
- [SourceNode.prototype.toStringWithSourceMap([startOfSourceMap])](#sourcenodeprototypetostringwithsourcemapstartofsourcemap) |
||||||
|
|
||||||
|
<!-- END doctoc generated TOC please keep comment here to allow auto update --> |
||||||
|
|
||||||
|
## Examples |
||||||
|
|
||||||
|
### Consuming a source map |
||||||
|
|
||||||
|
```js |
||||||
|
var rawSourceMap = { |
||||||
|
version: 3, |
||||||
|
file: 'min.js', |
||||||
|
names: ['bar', 'baz', 'n'], |
||||||
|
sources: ['one.js', 'two.js'], |
||||||
|
sourceRoot: 'http://example.com/www/js/', |
||||||
|
mappings: 'CAAC,IAAI,IAAM,SAAUA,GAClB,OAAOC,IAAID;CCDb,IAAI,IAAM,SAAUE,GAClB,OAAOA' |
||||||
|
}; |
||||||
|
|
||||||
|
var smc = new SourceMapConsumer(rawSourceMap); |
||||||
|
|
||||||
|
console.log(smc.sources); |
||||||
|
// [ 'http://example.com/www/js/one.js', |
||||||
|
// 'http://example.com/www/js/two.js' ] |
||||||
|
|
||||||
|
console.log(smc.originalPositionFor({ |
||||||
|
line: 2, |
||||||
|
column: 28 |
||||||
|
})); |
||||||
|
// { source: 'http://example.com/www/js/two.js', |
||||||
|
// line: 2, |
||||||
|
// column: 10, |
||||||
|
// name: 'n' } |
||||||
|
|
||||||
|
console.log(smc.generatedPositionFor({ |
||||||
|
source: 'http://example.com/www/js/two.js', |
||||||
|
line: 2, |
||||||
|
column: 10 |
||||||
|
})); |
||||||
|
// { line: 2, column: 28 } |
||||||
|
|
||||||
|
smc.eachMapping(function (m) { |
||||||
|
// ... |
||||||
|
}); |
||||||
|
``` |
||||||
|
|
||||||
|
### Generating a source map |
||||||
|
|
||||||
|
In depth guide: |
||||||
|
[**Compiling to JavaScript, and Debugging with Source Maps**](https://hacks.mozilla.org/2013/05/compiling-to-javascript-and-debugging-with-source-maps/) |
||||||
|
|
||||||
|
#### With SourceNode (high level API) |
||||||
|
|
||||||
|
```js |
||||||
|
function compile(ast) { |
||||||
|
switch (ast.type) { |
||||||
|
case 'BinaryExpression': |
||||||
|
return new SourceNode( |
||||||
|
ast.location.line, |
||||||
|
ast.location.column, |
||||||
|
ast.location.source, |
||||||
|
[compile(ast.left), " + ", compile(ast.right)] |
||||||
|
); |
||||||
|
case 'Literal': |
||||||
|
return new SourceNode( |
||||||
|
ast.location.line, |
||||||
|
ast.location.column, |
||||||
|
ast.location.source, |
||||||
|
String(ast.value) |
||||||
|
); |
||||||
|
// ... |
||||||
|
default: |
||||||
|
throw new Error("Bad AST"); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
var ast = parse("40 + 2", "add.js"); |
||||||
|
console.log(compile(ast).toStringWithSourceMap({ |
||||||
|
file: 'add.js' |
||||||
|
})); |
||||||
|
// { code: '40 + 2', |
||||||
|
// map: [object SourceMapGenerator] } |
||||||
|
``` |
||||||
|
|
||||||
|
#### With SourceMapGenerator (low level API) |
||||||
|
|
||||||
|
```js |
||||||
|
var map = new SourceMapGenerator({ |
||||||
|
file: "source-mapped.js" |
||||||
|
}); |
||||||
|
|
||||||
|
map.addMapping({ |
||||||
|
generated: { |
||||||
|
line: 10, |
||||||
|
column: 35 |
||||||
|
}, |
||||||
|
source: "foo.js", |
||||||
|
original: { |
||||||
|
line: 33, |
||||||
|
column: 2 |
||||||
|
}, |
||||||
|
name: "christopher" |
||||||
|
}); |
||||||
|
|
||||||
|
console.log(map.toString()); |
||||||
|
// '{"version":3,"file":"source-mapped.js","sources":["foo.js"],"names":["christopher"],"mappings":";;;;;;;;;mCAgCEA"}' |
||||||
|
``` |
||||||
|
|
||||||
|
## API |
||||||
|
|
||||||
|
Get a reference to the module: |
||||||
|
|
||||||
|
```js |
||||||
|
// Node.js |
||||||
|
var sourceMap = require('source-map'); |
||||||
|
|
||||||
|
// Browser builds |
||||||
|
var sourceMap = window.sourceMap; |
||||||
|
|
||||||
|
// Inside Firefox |
||||||
|
const sourceMap = require("devtools/toolkit/sourcemap/source-map.js"); |
||||||
|
``` |
||||||
|
|
||||||
|
### SourceMapConsumer |
||||||
|
|
||||||
|
A SourceMapConsumer instance represents a parsed source map which we can query |
||||||
|
for information about the original file positions by giving it a file position |
||||||
|
in the generated source. |
||||||
|
|
||||||
|
#### new SourceMapConsumer(rawSourceMap) |
||||||
|
|
||||||
|
The only parameter is the raw source map (either as a string which can be |
||||||
|
`JSON.parse`'d, or an object). According to the spec, source maps have the |
||||||
|
following attributes: |
||||||
|
|
||||||
|
* `version`: Which version of the source map spec this map is following. |
||||||
|
|
||||||
|
* `sources`: An array of URLs to the original source files. |
||||||
|
|
||||||
|
* `names`: An array of identifiers which can be referenced by individual |
||||||
|
mappings. |
||||||
|
|
||||||
|
* `sourceRoot`: Optional. The URL root from which all sources are relative. |
||||||
|
|
||||||
|
* `sourcesContent`: Optional. An array of contents of the original source files. |
||||||
|
|
||||||
|
* `mappings`: A string of base64 VLQs which contain the actual mappings. |
||||||
|
|
||||||
|
* `file`: Optional. The generated filename this source map is associated with. |
||||||
|
|
||||||
|
```js |
||||||
|
var consumer = new sourceMap.SourceMapConsumer(rawSourceMapJsonData); |
||||||
|
``` |
||||||
|
|
||||||
|
#### SourceMapConsumer.prototype.computeColumnSpans() |
||||||
|
|
||||||
|
Compute the last column for each generated mapping. The last column is |
||||||
|
inclusive. |
||||||
|
|
||||||
|
```js |
||||||
|
// Before: |
||||||
|
consumer.allGeneratedPositionsFor({ line: 2, source: "foo.coffee" }) |
||||||
|
// [ { line: 2, |
||||||
|
// column: 1 }, |
||||||
|
// { line: 2, |
||||||
|
// column: 10 }, |
||||||
|
// { line: 2, |
||||||
|
// column: 20 } ] |
||||||
|
|
||||||
|
consumer.computeColumnSpans(); |
||||||
|
|
||||||
|
// After: |
||||||
|
consumer.allGeneratedPositionsFor({ line: 2, source: "foo.coffee" }) |
||||||
|
// [ { line: 2, |
||||||
|
// column: 1, |
||||||
|
// lastColumn: 9 }, |
||||||
|
// { line: 2, |
||||||
|
// column: 10, |
||||||
|
// lastColumn: 19 }, |
||||||
|
// { line: 2, |
||||||
|
// column: 20, |
||||||
|
// lastColumn: Infinity } ] |
||||||
|
|
||||||
|
``` |
||||||
|
|
||||||
|
#### SourceMapConsumer.prototype.originalPositionFor(generatedPosition) |
||||||
|
|
||||||
|
Returns the original source, line, and column information for the generated |
||||||
|
source's line and column positions provided. The only argument is an object with |
||||||
|
the following properties: |
||||||
|
|
||||||
|
* `line`: The line number in the generated source. Line numbers in |
||||||
|
this library are 1-based (note that the underlying source map |
||||||
|
specification uses 0-based line numbers -- this library handles the |
||||||
|
translation). |
||||||
|
|
||||||
|
* `column`: The column number in the generated source. Column numbers |
||||||
|
in this library are 0-based. |
||||||
|
|
||||||
|
* `bias`: Either `SourceMapConsumer.GREATEST_LOWER_BOUND` or |
||||||
|
`SourceMapConsumer.LEAST_UPPER_BOUND`. Specifies whether to return the closest |
||||||
|
element that is smaller than or greater than the one we are searching for, |
||||||
|
respectively, if the exact element cannot be found. Defaults to |
||||||
|
`SourceMapConsumer.GREATEST_LOWER_BOUND`. |
||||||
|
|
||||||
|
and an object is returned with the following properties: |
||||||
|
|
||||||
|
* `source`: The original source file, or null if this information is not |
||||||
|
available. |
||||||
|
|
||||||
|
* `line`: The line number in the original source, or null if this information is |
||||||
|
not available. The line number is 1-based. |
||||||
|
|
||||||
|
* `column`: The column number in the original source, or null if this |
||||||
|
information is not available. The column number is 0-based. |
||||||
|
|
||||||
|
* `name`: The original identifier, or null if this information is not available. |
||||||
|
|
||||||
|
```js |
||||||
|
consumer.originalPositionFor({ line: 2, column: 10 }) |
||||||
|
// { source: 'foo.coffee', |
||||||
|
// line: 2, |
||||||
|
// column: 2, |
||||||
|
// name: null } |
||||||
|
|
||||||
|
consumer.originalPositionFor({ line: 99999999999999999, column: 999999999999999 }) |
||||||
|
// { source: null, |
||||||
|
// line: null, |
||||||
|
// column: null, |
||||||
|
// name: null } |
||||||
|
``` |
||||||
|
|
||||||
|
#### SourceMapConsumer.prototype.generatedPositionFor(originalPosition) |
||||||
|
|
||||||
|
Returns the generated line and column information for the original source, |
||||||
|
line, and column positions provided. The only argument is an object with |
||||||
|
the following properties: |
||||||
|
|
||||||
|
* `source`: The filename of the original source. |
||||||
|
|
||||||
|
* `line`: The line number in the original source. The line number is |
||||||
|
1-based. |
||||||
|
|
||||||
|
* `column`: The column number in the original source. The column |
||||||
|
number is 0-based. |
||||||
|
|
||||||
|
and an object is returned with the following properties: |
||||||
|
|
||||||
|
* `line`: The line number in the generated source, or null. The line |
||||||
|
number is 1-based. |
||||||
|
|
||||||
|
* `column`: The column number in the generated source, or null. The |
||||||
|
column number is 0-based. |
||||||
|
|
||||||
|
```js |
||||||
|
consumer.generatedPositionFor({ source: "example.js", line: 2, column: 10 }) |
||||||
|
// { line: 1, |
||||||
|
// column: 56 } |
||||||
|
``` |
||||||
|
|
||||||
|
#### SourceMapConsumer.prototype.allGeneratedPositionsFor(originalPosition) |
||||||
|
|
||||||
|
Returns all generated line and column information for the original source, line, |
||||||
|
and column provided. If no column is provided, returns all mappings |
||||||
|
corresponding to a either the line we are searching for or the next closest line |
||||||
|
that has any mappings. Otherwise, returns all mappings corresponding to the |
||||||
|
given line and either the column we are searching for or the next closest column |
||||||
|
that has any offsets. |
||||||
|
|
||||||
|
The only argument is an object with the following properties: |
||||||
|
|
||||||
|
* `source`: The filename of the original source. |
||||||
|
|
||||||
|
* `line`: The line number in the original source. The line number is |
||||||
|
1-based. |
||||||
|
|
||||||
|
* `column`: Optional. The column number in the original source. The |
||||||
|
column number is 0-based. |
||||||
|
|
||||||
|
and an array of objects is returned, each with the following properties: |
||||||
|
|
||||||
|
* `line`: The line number in the generated source, or null. The line |
||||||
|
number is 1-based. |
||||||
|
|
||||||
|
* `column`: The column number in the generated source, or null. The |
||||||
|
column number is 0-based. |
||||||
|
|
||||||
|
```js |
||||||
|
consumer.allGeneratedpositionsfor({ line: 2, source: "foo.coffee" }) |
||||||
|
// [ { line: 2, |
||||||
|
// column: 1 }, |
||||||
|
// { line: 2, |
||||||
|
// column: 10 }, |
||||||
|
// { line: 2, |
||||||
|
// column: 20 } ] |
||||||
|
``` |
||||||
|
|
||||||
|
#### SourceMapConsumer.prototype.hasContentsOfAllSources() |
||||||
|
|
||||||
|
Return true if we have the embedded source content for every source listed in |
||||||
|
the source map, false otherwise. |
||||||
|
|
||||||
|
In other words, if this method returns `true`, then |
||||||
|
`consumer.sourceContentFor(s)` will succeed for every source `s` in |
||||||
|
`consumer.sources`. |
||||||
|
|
||||||
|
```js |
||||||
|
// ... |
||||||
|
if (consumer.hasContentsOfAllSources()) { |
||||||
|
consumerReadyCallback(consumer); |
||||||
|
} else { |
||||||
|
fetchSources(consumer, consumerReadyCallback); |
||||||
|
} |
||||||
|
// ... |
||||||
|
``` |
||||||
|
|
||||||
|
#### SourceMapConsumer.prototype.sourceContentFor(source[, returnNullOnMissing]) |
||||||
|
|
||||||
|
Returns the original source content for the source provided. The only |
||||||
|
argument is the URL of the original source file. |
||||||
|
|
||||||
|
If the source content for the given source is not found, then an error is |
||||||
|
thrown. Optionally, pass `true` as the second param to have `null` returned |
||||||
|
instead. |
||||||
|
|
||||||
|
```js |
||||||
|
consumer.sources |
||||||
|
// [ "my-cool-lib.clj" ] |
||||||
|
|
||||||
|
consumer.sourceContentFor("my-cool-lib.clj") |
||||||
|
// "..." |
||||||
|
|
||||||
|
consumer.sourceContentFor("this is not in the source map"); |
||||||
|
// Error: "this is not in the source map" is not in the source map |
||||||
|
|
||||||
|
consumer.sourceContentFor("this is not in the source map", true); |
||||||
|
// null |
||||||
|
``` |
||||||
|
|
||||||
|
#### SourceMapConsumer.prototype.eachMapping(callback, context, order) |
||||||
|
|
||||||
|
Iterate over each mapping between an original source/line/column and a |
||||||
|
generated line/column in this source map. |
||||||
|
|
||||||
|
* `callback`: The function that is called with each mapping. Mappings have the |
||||||
|
form `{ source, generatedLine, generatedColumn, originalLine, originalColumn, |
||||||
|
name }` |
||||||
|
|
||||||
|
* `context`: Optional. If specified, this object will be the value of `this` |
||||||
|
every time that `callback` is called. |
||||||
|
|
||||||
|
* `order`: Either `SourceMapConsumer.GENERATED_ORDER` or |
||||||
|
`SourceMapConsumer.ORIGINAL_ORDER`. Specifies whether you want to iterate over |
||||||
|
the mappings sorted by the generated file's line/column order or the |
||||||
|
original's source/line/column order, respectively. Defaults to |
||||||
|
`SourceMapConsumer.GENERATED_ORDER`. |
||||||
|
|
||||||
|
```js |
||||||
|
consumer.eachMapping(function (m) { console.log(m); }) |
||||||
|
// ... |
||||||
|
// { source: 'illmatic.js', |
||||||
|
// generatedLine: 1, |
||||||
|
// generatedColumn: 0, |
||||||
|
// originalLine: 1, |
||||||
|
// originalColumn: 0, |
||||||
|
// name: null } |
||||||
|
// { source: 'illmatic.js', |
||||||
|
// generatedLine: 2, |
||||||
|
// generatedColumn: 0, |
||||||
|
// originalLine: 2, |
||||||
|
// originalColumn: 0, |
||||||
|
// name: null } |
||||||
|
// ... |
||||||
|
``` |
||||||
|
### SourceMapGenerator |
||||||
|
|
||||||
|
An instance of the SourceMapGenerator represents a source map which is being |
||||||
|
built incrementally. |
||||||
|
|
||||||
|
#### new SourceMapGenerator([startOfSourceMap]) |
||||||
|
|
||||||
|
You may pass an object with the following properties: |
||||||
|
|
||||||
|
* `file`: The filename of the generated source that this source map is |
||||||
|
associated with. |
||||||
|
|
||||||
|
* `sourceRoot`: A root for all relative URLs in this source map. |
||||||
|
|
||||||
|
* `skipValidation`: Optional. When `true`, disables validation of mappings as |
||||||
|
they are added. This can improve performance but should be used with |
||||||
|
discretion, as a last resort. Even then, one should avoid using this flag when |
||||||
|
running tests, if possible. |
||||||
|
|
||||||
|
```js |
||||||
|
var generator = new sourceMap.SourceMapGenerator({ |
||||||
|
file: "my-generated-javascript-file.js", |
||||||
|
sourceRoot: "http://example.com/app/js/" |
||||||
|
}); |
||||||
|
``` |
||||||
|
|
||||||
|
#### SourceMapGenerator.fromSourceMap(sourceMapConsumer) |
||||||
|
|
||||||
|
Creates a new `SourceMapGenerator` from an existing `SourceMapConsumer` instance. |
||||||
|
|
||||||
|
* `sourceMapConsumer` The SourceMap. |
||||||
|
|
||||||
|
```js |
||||||
|
var generator = sourceMap.SourceMapGenerator.fromSourceMap(consumer); |
||||||
|
``` |
||||||
|
|
||||||
|
#### SourceMapGenerator.prototype.addMapping(mapping) |
||||||
|
|
||||||
|
Add a single mapping from original source line and column to the generated |
||||||
|
source's line and column for this source map being created. The mapping object |
||||||
|
should have the following properties: |
||||||
|
|
||||||
|
* `generated`: An object with the generated line and column positions. |
||||||
|
|
||||||
|
* `original`: An object with the original line and column positions. |
||||||
|
|
||||||
|
* `source`: The original source file (relative to the sourceRoot). |
||||||
|
|
||||||
|
* `name`: An optional original token name for this mapping. |
||||||
|
|
||||||
|
```js |
||||||
|
generator.addMapping({ |
||||||
|
source: "module-one.scm", |
||||||
|
original: { line: 128, column: 0 }, |
||||||
|
generated: { line: 3, column: 456 } |
||||||
|
}) |
||||||
|
``` |
||||||
|
|
||||||
|
#### SourceMapGenerator.prototype.setSourceContent(sourceFile, sourceContent) |
||||||
|
|
||||||
|
Set the source content for an original source file. |
||||||
|
|
||||||
|
* `sourceFile` the URL of the original source file. |
||||||
|
|
||||||
|
* `sourceContent` the content of the source file. |
||||||
|
|
||||||
|
```js |
||||||
|
generator.setSourceContent("module-one.scm", |
||||||
|
fs.readFileSync("path/to/module-one.scm")) |
||||||
|
``` |
||||||
|
|
||||||
|
#### SourceMapGenerator.prototype.applySourceMap(sourceMapConsumer[, sourceFile[, sourceMapPath]]) |
||||||
|
|
||||||
|
Applies a SourceMap for a source file to the SourceMap. |
||||||
|
Each mapping to the supplied source file is rewritten using the |
||||||
|
supplied SourceMap. Note: The resolution for the resulting mappings |
||||||
|
is the minimum of this map and the supplied map. |
||||||
|
|
||||||
|
* `sourceMapConsumer`: The SourceMap to be applied. |
||||||
|
|
||||||
|
* `sourceFile`: Optional. The filename of the source file. |
||||||
|
If omitted, sourceMapConsumer.file will be used, if it exists. |
||||||
|
Otherwise an error will be thrown. |
||||||
|
|
||||||
|
* `sourceMapPath`: Optional. The dirname of the path to the SourceMap |
||||||
|
to be applied. If relative, it is relative to the SourceMap. |
||||||
|
|
||||||
|
This parameter is needed when the two SourceMaps aren't in the same |
||||||
|
directory, and the SourceMap to be applied contains relative source |
||||||
|
paths. If so, those relative source paths need to be rewritten |
||||||
|
relative to the SourceMap. |
||||||
|
|
||||||
|
If omitted, it is assumed that both SourceMaps are in the same directory, |
||||||
|
thus not needing any rewriting. (Supplying `'.'` has the same effect.) |
||||||
|
|
||||||
|
#### SourceMapGenerator.prototype.toString() |
||||||
|
|
||||||
|
Renders the source map being generated to a string. |
||||||
|
|
||||||
|
```js |
||||||
|
generator.toString() |
||||||
|
// '{"version":3,"sources":["module-one.scm"],"names":[],"mappings":"...snip...","file":"my-generated-javascript-file.js","sourceRoot":"http://example.com/app/js/"}' |
||||||
|
``` |
||||||
|
|
||||||
|
### SourceNode |
||||||
|
|
||||||
|
SourceNodes provide a way to abstract over interpolating and/or concatenating |
||||||
|
snippets of generated JavaScript source code, while maintaining the line and |
||||||
|
column information associated between those snippets and the original source |
||||||
|
code. This is useful as the final intermediate representation a compiler might |
||||||
|
use before outputting the generated JS and source map. |
||||||
|
|
||||||
|
#### new SourceNode([line, column, source[, chunk[, name]]]) |
||||||
|
|
||||||
|
* `line`: The original line number associated with this source node, or null if |
||||||
|
it isn't associated with an original line. The line number is 1-based. |
||||||
|
|
||||||
|
* `column`: The original column number associated with this source node, or null |
||||||
|
if it isn't associated with an original column. The column number |
||||||
|
is 0-based. |
||||||
|
|
||||||
|
* `source`: The original source's filename; null if no filename is provided. |
||||||
|
|
||||||
|
* `chunk`: Optional. Is immediately passed to `SourceNode.prototype.add`, see |
||||||
|
below. |
||||||
|
|
||||||
|
* `name`: Optional. The original identifier. |
||||||
|
|
||||||
|
```js |
||||||
|
var node = new SourceNode(1, 2, "a.cpp", [ |
||||||
|
new SourceNode(3, 4, "b.cpp", "extern int status;\n"), |
||||||
|
new SourceNode(5, 6, "c.cpp", "std::string* make_string(size_t n);\n"), |
||||||
|
new SourceNode(7, 8, "d.cpp", "int main(int argc, char** argv) {}\n"), |
||||||
|
]); |
||||||
|
``` |
||||||
|
|
||||||
|
#### SourceNode.fromStringWithSourceMap(code, sourceMapConsumer[, relativePath]) |
||||||
|
|
||||||
|
Creates a SourceNode from generated code and a SourceMapConsumer. |
||||||
|
|
||||||
|
* `code`: The generated code |
||||||
|
|
||||||
|
* `sourceMapConsumer` The SourceMap for the generated code |
||||||
|
|
||||||
|
* `relativePath` The optional path that relative sources in `sourceMapConsumer` |
||||||
|
should be relative to. |
||||||
|
|
||||||
|
```js |
||||||
|
var consumer = new SourceMapConsumer(fs.readFileSync("path/to/my-file.js.map", "utf8")); |
||||||
|
var node = SourceNode.fromStringWithSourceMap(fs.readFileSync("path/to/my-file.js"), |
||||||
|
consumer); |
||||||
|
``` |
||||||
|
|
||||||
|
#### SourceNode.prototype.add(chunk) |
||||||
|
|
||||||
|
Add a chunk of generated JS to this source node. |
||||||
|
|
||||||
|
* `chunk`: A string snippet of generated JS code, another instance of |
||||||
|
`SourceNode`, or an array where each member is one of those things. |
||||||
|
|
||||||
|
```js |
||||||
|
node.add(" + "); |
||||||
|
node.add(otherNode); |
||||||
|
node.add([leftHandOperandNode, " + ", rightHandOperandNode]); |
||||||
|
``` |
||||||
|
|
||||||
|
#### SourceNode.prototype.prepend(chunk) |
||||||
|
|
||||||
|
Prepend a chunk of generated JS to this source node. |
||||||
|
|
||||||
|
* `chunk`: A string snippet of generated JS code, another instance of |
||||||
|
`SourceNode`, or an array where each member is one of those things. |
||||||
|
|
||||||
|
```js |
||||||
|
node.prepend("/** Build Id: f783haef86324gf **/\n\n"); |
||||||
|
``` |
||||||
|
|
||||||
|
#### SourceNode.prototype.setSourceContent(sourceFile, sourceContent) |
||||||
|
|
||||||
|
Set the source content for a source file. This will be added to the |
||||||
|
`SourceMap` in the `sourcesContent` field. |
||||||
|
|
||||||
|
* `sourceFile`: The filename of the source file |
||||||
|
|
||||||
|
* `sourceContent`: The content of the source file |
||||||
|
|
||||||
|
```js |
||||||
|
node.setSourceContent("module-one.scm", |
||||||
|
fs.readFileSync("path/to/module-one.scm")) |
||||||
|
``` |
||||||
|
|
||||||
|
#### SourceNode.prototype.walk(fn) |
||||||
|
|
||||||
|
Walk over the tree of JS snippets in this node and its children. The walking |
||||||
|
function is called once for each snippet of JS and is passed that snippet and |
||||||
|
the its original associated source's line/column location. |
||||||
|
|
||||||
|
* `fn`: The traversal function. |
||||||
|
|
||||||
|
```js |
||||||
|
var node = new SourceNode(1, 2, "a.js", [ |
||||||
|
new SourceNode(3, 4, "b.js", "uno"), |
||||||
|
"dos", |
||||||
|
[ |
||||||
|
"tres", |
||||||
|
new SourceNode(5, 6, "c.js", "quatro") |
||||||
|
] |
||||||
|
]); |
||||||
|
|
||||||
|
node.walk(function (code, loc) { console.log("WALK:", code, loc); }) |
||||||
|
// WALK: uno { source: 'b.js', line: 3, column: 4, name: null } |
||||||
|
// WALK: dos { source: 'a.js', line: 1, column: 2, name: null } |
||||||
|
// WALK: tres { source: 'a.js', line: 1, column: 2, name: null } |
||||||
|
// WALK: quatro { source: 'c.js', line: 5, column: 6, name: null } |
||||||
|
``` |
||||||
|
|
||||||
|
#### SourceNode.prototype.walkSourceContents(fn) |
||||||
|
|
||||||
|
Walk over the tree of SourceNodes. The walking function is called for each |
||||||
|
source file content and is passed the filename and source content. |
||||||
|
|
||||||
|
* `fn`: The traversal function. |
||||||
|
|
||||||
|
```js |
||||||
|
var a = new SourceNode(1, 2, "a.js", "generated from a"); |
||||||
|
a.setSourceContent("a.js", "original a"); |
||||||
|
var b = new SourceNode(1, 2, "b.js", "generated from b"); |
||||||
|
b.setSourceContent("b.js", "original b"); |
||||||
|
var c = new SourceNode(1, 2, "c.js", "generated from c"); |
||||||
|
c.setSourceContent("c.js", "original c"); |
||||||
|
|
||||||
|
var node = new SourceNode(null, null, null, [a, b, c]); |
||||||
|
node.walkSourceContents(function (source, contents) { console.log("WALK:", source, ":", contents); }) |
||||||
|
// WALK: a.js : original a |
||||||
|
// WALK: b.js : original b |
||||||
|
// WALK: c.js : original c |
||||||
|
``` |
||||||
|
|
||||||
|
#### SourceNode.prototype.join(sep) |
||||||
|
|
||||||
|
Like `Array.prototype.join` except for SourceNodes. Inserts the separator |
||||||
|
between each of this source node's children. |
||||||
|
|
||||||
|
* `sep`: The separator. |
||||||
|
|
||||||
|
```js |
||||||
|
var lhs = new SourceNode(1, 2, "a.rs", "my_copy"); |
||||||
|
var operand = new SourceNode(3, 4, "a.rs", "="); |
||||||
|
var rhs = new SourceNode(5, 6, "a.rs", "orig.clone()"); |
||||||
|
|
||||||
|
var node = new SourceNode(null, null, null, [ lhs, operand, rhs ]); |
||||||
|
var joinedNode = node.join(" "); |
||||||
|
``` |
||||||
|
|
||||||
|
#### SourceNode.prototype.replaceRight(pattern, replacement) |
||||||
|
|
||||||
|
Call `String.prototype.replace` on the very right-most source snippet. Useful |
||||||
|
for trimming white space from the end of a source node, etc. |
||||||
|
|
||||||
|
* `pattern`: The pattern to replace. |
||||||
|
|
||||||
|
* `replacement`: The thing to replace the pattern with. |
||||||
|
|
||||||
|
```js |
||||||
|
// Trim trailing white space. |
||||||
|
node.replaceRight(/\s*$/, ""); |
||||||
|
``` |
||||||
|
|
||||||
|
#### SourceNode.prototype.toString() |
||||||
|
|
||||||
|
Return the string representation of this source node. Walks over the tree and |
||||||
|
concatenates all the various snippets together to one string. |
||||||
|
|
||||||
|
```js |
||||||
|
var node = new SourceNode(1, 2, "a.js", [ |
||||||
|
new SourceNode(3, 4, "b.js", "uno"), |
||||||
|
"dos", |
||||||
|
[ |
||||||
|
"tres", |
||||||
|
new SourceNode(5, 6, "c.js", "quatro") |
||||||
|
] |
||||||
|
]); |
||||||
|
|
||||||
|
node.toString() |
||||||
|
// 'unodostresquatro' |
||||||
|
``` |
||||||
|
|
||||||
|
#### SourceNode.prototype.toStringWithSourceMap([startOfSourceMap]) |
||||||
|
|
||||||
|
Returns the string representation of this tree of source nodes, plus a |
||||||
|
SourceMapGenerator which contains all the mappings between the generated and |
||||||
|
original sources. |
||||||
|
|
||||||
|
The arguments are the same as those to `new SourceMapGenerator`. |
||||||
|
|
||||||
|
```js |
||||||
|
var node = new SourceNode(1, 2, "a.js", [ |
||||||
|
new SourceNode(3, 4, "b.js", "uno"), |
||||||
|
"dos", |
||||||
|
[ |
||||||
|
"tres", |
||||||
|
new SourceNode(5, 6, "c.js", "quatro") |
||||||
|
] |
||||||
|
]); |
||||||
|
|
||||||
|
node.toStringWithSourceMap({ file: "my-output-file.js" }) |
||||||
|
// { code: 'unodostresquatro', |
||||||
|
// map: [object SourceMapGenerator] } |
||||||
|
``` |
@ -0,0 +1,121 @@ |
|||||||
|
/* -*- Mode: js; js-indent-level: 2; -*- */ |
||||||
|
/* |
||||||
|
* Copyright 2011 Mozilla Foundation and contributors |
||||||
|
* Licensed under the New BSD license. See LICENSE or: |
||||||
|
* http://opensource.org/licenses/BSD-3-Clause
|
||||||
|
*/ |
||||||
|
|
||||||
|
var util = require('./util'); |
||||||
|
var has = Object.prototype.hasOwnProperty; |
||||||
|
var hasNativeMap = typeof Map !== "undefined"; |
||||||
|
|
||||||
|
/** |
||||||
|
* A data structure which is a combination of an array and a set. Adding a new |
||||||
|
* member is O(1), testing for membership is O(1), and finding the index of an |
||||||
|
* element is O(1). Removing elements from the set is not supported. Only |
||||||
|
* strings are supported for membership. |
||||||
|
*/ |
||||||
|
function ArraySet() { |
||||||
|
this._array = []; |
||||||
|
this._set = hasNativeMap ? new Map() : Object.create(null); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Static method for creating ArraySet instances from an existing array. |
||||||
|
*/ |
||||||
|
ArraySet.fromArray = function ArraySet_fromArray(aArray, aAllowDuplicates) { |
||||||
|
var set = new ArraySet(); |
||||||
|
for (var i = 0, len = aArray.length; i < len; i++) { |
||||||
|
set.add(aArray[i], aAllowDuplicates); |
||||||
|
} |
||||||
|
return set; |
||||||
|
}; |
||||||
|
|
||||||
|
/** |
||||||
|
* Return how many unique items are in this ArraySet. If duplicates have been |
||||||
|
* added, than those do not count towards the size. |
||||||
|
* |
||||||
|
* @returns Number |
||||||
|
*/ |
||||||
|
ArraySet.prototype.size = function ArraySet_size() { |
||||||
|
return hasNativeMap ? this._set.size : Object.getOwnPropertyNames(this._set).length; |
||||||
|
}; |
||||||
|
|
||||||
|
/** |
||||||
|
* Add the given string to this set. |
||||||
|
* |
||||||
|
* @param String aStr |
||||||
|
*/ |
||||||
|
ArraySet.prototype.add = function ArraySet_add(aStr, aAllowDuplicates) { |
||||||
|
var sStr = hasNativeMap ? aStr : util.toSetString(aStr); |
||||||
|
var isDuplicate = hasNativeMap ? this.has(aStr) : has.call(this._set, sStr); |
||||||
|
var idx = this._array.length; |
||||||
|
if (!isDuplicate || aAllowDuplicates) { |
||||||
|
this._array.push(aStr); |
||||||
|
} |
||||||
|
if (!isDuplicate) { |
||||||
|
if (hasNativeMap) { |
||||||
|
this._set.set(aStr, idx); |
||||||
|
} else { |
||||||
|
this._set[sStr] = idx; |
||||||
|
} |
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
/** |
||||||
|
* Is the given string a member of this set? |
||||||
|
* |
||||||
|
* @param String aStr |
||||||
|
*/ |
||||||
|
ArraySet.prototype.has = function ArraySet_has(aStr) { |
||||||
|
if (hasNativeMap) { |
||||||
|
return this._set.has(aStr); |
||||||
|
} else { |
||||||
|
var sStr = util.toSetString(aStr); |
||||||
|
return has.call(this._set, sStr); |
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
/** |
||||||
|
* What is the index of the given string in the array? |
||||||
|
* |
||||||
|
* @param String aStr |
||||||
|
*/ |
||||||
|
ArraySet.prototype.indexOf = function ArraySet_indexOf(aStr) { |
||||||
|
if (hasNativeMap) { |
||||||
|
var idx = this._set.get(aStr); |
||||||
|
if (idx >= 0) { |
||||||
|
return idx; |
||||||
|
} |
||||||
|
} else { |
||||||
|
var sStr = util.toSetString(aStr); |
||||||
|
if (has.call(this._set, sStr)) { |
||||||
|
return this._set[sStr]; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
throw new Error('"' + aStr + '" is not in the set.'); |
||||||
|
}; |
||||||
|
|
||||||
|
/** |
||||||
|
* What is the element at the given index? |
||||||
|
* |
||||||
|
* @param Number aIdx |
||||||
|
*/ |
||||||
|
ArraySet.prototype.at = function ArraySet_at(aIdx) { |
||||||
|
if (aIdx >= 0 && aIdx < this._array.length) { |
||||||
|
return this._array[aIdx]; |
||||||
|
} |
||||||
|
throw new Error('No element indexed by ' + aIdx); |
||||||
|
}; |
||||||
|
|
||||||
|
/** |
||||||
|
* Returns the array representation of this set (which has the proper indices |
||||||
|
* indicated by indexOf). Note that this is a copy of the internal array used |
||||||
|
* for storing the members so that no one can mess with internal state. |
||||||
|
*/ |
||||||
|
ArraySet.prototype.toArray = function ArraySet_toArray() { |
||||||
|
return this._array.slice(); |
||||||
|
}; |
||||||
|
|
||||||
|
exports.ArraySet = ArraySet; |
@ -0,0 +1,140 @@ |
|||||||
|
/* -*- Mode: js; js-indent-level: 2; -*- */ |
||||||
|
/* |
||||||
|
* Copyright 2011 Mozilla Foundation and contributors |
||||||
|
* Licensed under the New BSD license. See LICENSE or: |
||||||
|
* http://opensource.org/licenses/BSD-3-Clause
|
||||||
|
* |
||||||
|
* Based on the Base 64 VLQ implementation in Closure Compiler: |
||||||
|
* https://code.google.com/p/closure-compiler/source/browse/trunk/src/com/google/debugging/sourcemap/Base64VLQ.java
|
||||||
|
* |
||||||
|
* Copyright 2011 The Closure Compiler Authors. All rights reserved. |
||||||
|
* Redistribution and use in source and binary forms, with or without |
||||||
|
* modification, are permitted provided that the following conditions are |
||||||
|
* met: |
||||||
|
* |
||||||
|
* * Redistributions of source code must retain the above copyright |
||||||
|
* notice, this list of conditions and the following disclaimer. |
||||||
|
* * Redistributions in binary form must reproduce the above |
||||||
|
* copyright notice, this list of conditions and the following |
||||||
|
* disclaimer in the documentation and/or other materials provided |
||||||
|
* with the distribution. |
||||||
|
* * Neither the name of Google Inc. nor the names of its |
||||||
|
* contributors may be used to endorse or promote products derived |
||||||
|
* from this software without specific prior written permission. |
||||||
|
* |
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||||
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||||
|
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||||
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||||
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||||
|
*/ |
||||||
|
|
||||||
|
var base64 = require('./base64'); |
||||||
|
|
||||||
|
// A single base 64 digit can contain 6 bits of data. For the base 64 variable
|
||||||
|
// length quantities we use in the source map spec, the first bit is the sign,
|
||||||
|
// the next four bits are the actual value, and the 6th bit is the
|
||||||
|
// continuation bit. The continuation bit tells us whether there are more
|
||||||
|
// digits in this value following this digit.
|
||||||
|
//
|
||||||
|
// Continuation
|
||||||
|
// | Sign
|
||||||
|
// | |
|
||||||
|
// V V
|
||||||
|
// 101011
|
||||||
|
|
||||||
|
var VLQ_BASE_SHIFT = 5; |
||||||
|
|
||||||
|
// binary: 100000
|
||||||
|
var VLQ_BASE = 1 << VLQ_BASE_SHIFT; |
||||||
|
|
||||||
|
// binary: 011111
|
||||||
|
var VLQ_BASE_MASK = VLQ_BASE - 1; |
||||||
|
|
||||||
|
// binary: 100000
|
||||||
|
var VLQ_CONTINUATION_BIT = VLQ_BASE; |
||||||
|
|
||||||
|
/** |
||||||
|
* Converts from a two-complement value to a value where the sign bit is |
||||||
|
* placed in the least significant bit. For example, as decimals: |
||||||
|
* 1 becomes 2 (10 binary), -1 becomes 3 (11 binary) |
||||||
|
* 2 becomes 4 (100 binary), -2 becomes 5 (101 binary) |
||||||
|
*/ |
||||||
|
function toVLQSigned(aValue) { |
||||||
|
return aValue < 0 |
||||||
|
? ((-aValue) << 1) + 1 |
||||||
|
: (aValue << 1) + 0; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Converts to a two-complement value from a value where the sign bit is |
||||||
|
* placed in the least significant bit. For example, as decimals: |
||||||
|
* 2 (10 binary) becomes 1, 3 (11 binary) becomes -1 |
||||||
|
* 4 (100 binary) becomes 2, 5 (101 binary) becomes -2 |
||||||
|
*/ |
||||||
|
function fromVLQSigned(aValue) { |
||||||
|
var isNegative = (aValue & 1) === 1; |
||||||
|
var shifted = aValue >> 1; |
||||||
|
return isNegative |
||||||
|
? -shifted |
||||||
|
: shifted; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Returns the base 64 VLQ encoded value. |
||||||
|
*/ |
||||||
|
exports.encode = function base64VLQ_encode(aValue) { |
||||||
|
var encoded = ""; |
||||||
|
var digit; |
||||||
|
|
||||||
|
var vlq = toVLQSigned(aValue); |
||||||
|
|
||||||
|
do { |
||||||
|
digit = vlq & VLQ_BASE_MASK; |
||||||
|
vlq >>>= VLQ_BASE_SHIFT; |
||||||
|
if (vlq > 0) { |
||||||
|
// There are still more digits in this value, so we must make sure the
|
||||||
|
// continuation bit is marked.
|
||||||
|
digit |= VLQ_CONTINUATION_BIT; |
||||||
|
} |
||||||
|
encoded += base64.encode(digit); |
||||||
|
} while (vlq > 0); |
||||||
|
|
||||||
|
return encoded; |
||||||
|
}; |
||||||
|
|
||||||
|
/** |
||||||
|
* Decodes the next base 64 VLQ value from the given string and returns the |
||||||
|
* value and the rest of the string via the out parameter. |
||||||
|
*/ |
||||||
|
exports.decode = function base64VLQ_decode(aStr, aIndex, aOutParam) { |
||||||
|
var strLen = aStr.length; |
||||||
|
var result = 0; |
||||||
|
var shift = 0; |
||||||
|
var continuation, digit; |
||||||
|
|
||||||
|
do { |
||||||
|
if (aIndex >= strLen) { |
||||||
|
throw new Error("Expected more digits in base 64 VLQ value."); |
||||||
|
} |
||||||
|
|
||||||
|
digit = base64.decode(aStr.charCodeAt(aIndex++)); |
||||||
|
if (digit === -1) { |
||||||
|
throw new Error("Invalid base64 digit: " + aStr.charAt(aIndex - 1)); |
||||||
|
} |
||||||
|
|
||||||
|
continuation = !!(digit & VLQ_CONTINUATION_BIT); |
||||||
|
digit &= VLQ_BASE_MASK; |
||||||
|
result = result + (digit << shift); |
||||||
|
shift += VLQ_BASE_SHIFT; |
||||||
|
} while (continuation); |
||||||
|
|
||||||
|
aOutParam.value = fromVLQSigned(result); |
||||||
|
aOutParam.rest = aIndex; |
||||||
|
}; |
@ -0,0 +1,67 @@ |
|||||||
|
/* -*- Mode: js; js-indent-level: 2; -*- */ |
||||||
|
/* |
||||||
|
* Copyright 2011 Mozilla Foundation and contributors |
||||||
|
* Licensed under the New BSD license. See LICENSE or: |
||||||
|
* http://opensource.org/licenses/BSD-3-Clause
|
||||||
|
*/ |
||||||
|
|
||||||
|
var intToCharMap = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'.split(''); |
||||||
|
|
||||||
|
/** |
||||||
|
* Encode an integer in the range of 0 to 63 to a single base 64 digit. |
||||||
|
*/ |
||||||
|
exports.encode = function (number) { |
||||||
|
if (0 <= number && number < intToCharMap.length) { |
||||||
|
return intToCharMap[number]; |
||||||
|
} |
||||||
|
throw new TypeError("Must be between 0 and 63: " + number); |
||||||
|
}; |
||||||
|
|
||||||
|
/** |
||||||
|
* Decode a single base 64 character code digit to an integer. Returns -1 on |
||||||
|
* failure. |
||||||
|
*/ |
||||||
|
exports.decode = function (charCode) { |
||||||
|
var bigA = 65; // 'A'
|
||||||
|
var bigZ = 90; // 'Z'
|
||||||
|
|
||||||
|
var littleA = 97; // 'a'
|
||||||
|
var littleZ = 122; // 'z'
|
||||||
|
|
||||||
|
var zero = 48; // '0'
|
||||||
|
var nine = 57; // '9'
|
||||||
|
|
||||||
|
var plus = 43; // '+'
|
||||||
|
var slash = 47; // '/'
|
||||||
|
|
||||||
|
var littleOffset = 26; |
||||||
|
var numberOffset = 52; |
||||||
|
|
||||||
|
// 0 - 25: ABCDEFGHIJKLMNOPQRSTUVWXYZ
|
||||||
|
if (bigA <= charCode && charCode <= bigZ) { |
||||||
|
return (charCode - bigA); |
||||||
|
} |
||||||
|
|
||||||
|
// 26 - 51: abcdefghijklmnopqrstuvwxyz
|
||||||
|
if (littleA <= charCode && charCode <= littleZ) { |
||||||
|
return (charCode - littleA + littleOffset); |
||||||
|
} |
||||||
|
|
||||||
|
// 52 - 61: 0123456789
|
||||||
|
if (zero <= charCode && charCode <= nine) { |
||||||
|
return (charCode - zero + numberOffset); |
||||||
|
} |
||||||
|
|
||||||
|
// 62: +
|
||||||
|
if (charCode == plus) { |
||||||
|
return 62; |
||||||
|
} |
||||||
|
|
||||||
|
// 63: /
|
||||||
|
if (charCode == slash) { |
||||||
|
return 63; |
||||||
|
} |
||||||
|
|
||||||
|
// Invalid base64 digit.
|
||||||
|
return -1; |
||||||
|
}; |
@ -0,0 +1,111 @@ |
|||||||
|
/* -*- Mode: js; js-indent-level: 2; -*- */ |
||||||
|
/* |
||||||
|
* Copyright 2011 Mozilla Foundation and contributors |
||||||
|
* Licensed under the New BSD license. See LICENSE or: |
||||||
|
* http://opensource.org/licenses/BSD-3-Clause
|
||||||
|
*/ |
||||||
|
|
||||||
|
exports.GREATEST_LOWER_BOUND = 1; |
||||||
|
exports.LEAST_UPPER_BOUND = 2; |
||||||
|
|
||||||
|
/** |
||||||
|
* Recursive implementation of binary search. |
||||||
|
* |
||||||
|
* @param aLow Indices here and lower do not contain the needle. |
||||||
|
* @param aHigh Indices here and higher do not contain the needle. |
||||||
|
* @param aNeedle The element being searched for. |
||||||
|
* @param aHaystack The non-empty array being searched. |
||||||
|
* @param aCompare Function which takes two elements and returns -1, 0, or 1. |
||||||
|
* @param aBias Either 'binarySearch.GREATEST_LOWER_BOUND' or |
||||||
|
* 'binarySearch.LEAST_UPPER_BOUND'. Specifies whether to return the |
||||||
|
* closest element that is smaller than or greater than the one we are |
||||||
|
* searching for, respectively, if the exact element cannot be found. |
||||||
|
*/ |
||||||
|
function recursiveSearch(aLow, aHigh, aNeedle, aHaystack, aCompare, aBias) { |
||||||
|
// This function terminates when one of the following is true:
|
||||||
|
//
|
||||||
|
// 1. We find the exact element we are looking for.
|
||||||
|
//
|
||||||
|
// 2. We did not find the exact element, but we can return the index of
|
||||||
|
// the next-closest element.
|
||||||
|
//
|
||||||
|
// 3. We did not find the exact element, and there is no next-closest
|
||||||
|
// element than the one we are searching for, so we return -1.
|
||||||
|
var mid = Math.floor((aHigh - aLow) / 2) + aLow; |
||||||
|
var cmp = aCompare(aNeedle, aHaystack[mid], true); |
||||||
|
if (cmp === 0) { |
||||||
|
// Found the element we are looking for.
|
||||||
|
return mid; |
||||||
|
} |
||||||
|
else if (cmp > 0) { |
||||||
|
// Our needle is greater than aHaystack[mid].
|
||||||
|
if (aHigh - mid > 1) { |
||||||
|
// The element is in the upper half.
|
||||||
|
return recursiveSearch(mid, aHigh, aNeedle, aHaystack, aCompare, aBias); |
||||||
|
} |
||||||
|
|
||||||
|
// The exact needle element was not found in this haystack. Determine if
|
||||||
|
// we are in termination case (3) or (2) and return the appropriate thing.
|
||||||
|
if (aBias == exports.LEAST_UPPER_BOUND) { |
||||||
|
return aHigh < aHaystack.length ? aHigh : -1; |
||||||
|
} else { |
||||||
|
return mid; |
||||||
|
} |
||||||
|
} |
||||||
|
else { |
||||||
|
// Our needle is less than aHaystack[mid].
|
||||||
|
if (mid - aLow > 1) { |
||||||
|
// The element is in the lower half.
|
||||||
|
return recursiveSearch(aLow, mid, aNeedle, aHaystack, aCompare, aBias); |
||||||
|
} |
||||||
|
|
||||||
|
// we are in termination case (3) or (2) and return the appropriate thing.
|
||||||
|
if (aBias == exports.LEAST_UPPER_BOUND) { |
||||||
|
return mid; |
||||||
|
} else { |
||||||
|
return aLow < 0 ? -1 : aLow; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* This is an implementation of binary search which will always try and return |
||||||
|
* the index of the closest element if there is no exact hit. This is because |
||||||
|
* mappings between original and generated line/col pairs are single points, |
||||||
|
* and there is an implicit region between each of them, so a miss just means |
||||||
|
* that you aren't on the very start of a region. |
||||||
|
* |
||||||
|
* @param aNeedle The element you are looking for. |
||||||
|
* @param aHaystack The array that is being searched. |
||||||
|
* @param aCompare A function which takes the needle and an element in the |
||||||
|
* array and returns -1, 0, or 1 depending on whether the needle is less |
||||||
|
* than, equal to, or greater than the element, respectively. |
||||||
|
* @param aBias Either 'binarySearch.GREATEST_LOWER_BOUND' or |
||||||
|
* 'binarySearch.LEAST_UPPER_BOUND'. Specifies whether to return the |
||||||
|
* closest element that is smaller than or greater than the one we are |
||||||
|
* searching for, respectively, if the exact element cannot be found. |
||||||
|
* Defaults to 'binarySearch.GREATEST_LOWER_BOUND'. |
||||||
|
*/ |
||||||
|
exports.search = function search(aNeedle, aHaystack, aCompare, aBias) { |
||||||
|
if (aHaystack.length === 0) { |
||||||
|
return -1; |
||||||
|
} |
||||||
|
|
||||||
|
var index = recursiveSearch(-1, aHaystack.length, aNeedle, aHaystack, |
||||||
|
aCompare, aBias || exports.GREATEST_LOWER_BOUND); |
||||||
|
if (index < 0) { |
||||||
|
return -1; |
||||||
|
} |
||||||
|
|
||||||
|
// We have found either the exact element, or the next-closest element than
|
||||||
|
// the one we are searching for. However, there may be more than one such
|
||||||
|
// element. Make sure we always return the smallest of these.
|
||||||
|
while (index - 1 >= 0) { |
||||||
|
if (aCompare(aHaystack[index], aHaystack[index - 1], true) !== 0) { |
||||||
|
break; |
||||||
|
} |
||||||
|
--index; |
||||||
|
} |
||||||
|
|
||||||
|
return index; |
||||||
|
}; |
@ -0,0 +1,79 @@ |
|||||||
|
/* -*- Mode: js; js-indent-level: 2; -*- */ |
||||||
|
/* |
||||||
|
* Copyright 2014 Mozilla Foundation and contributors |
||||||
|
* Licensed under the New BSD license. See LICENSE or: |
||||||
|
* http://opensource.org/licenses/BSD-3-Clause
|
||||||
|
*/ |
||||||
|
|
||||||
|
var util = require('./util'); |
||||||
|
|
||||||
|
/** |
||||||
|
* Determine whether mappingB is after mappingA with respect to generated |
||||||
|
* position. |
||||||
|
*/ |
||||||
|
function generatedPositionAfter(mappingA, mappingB) { |
||||||
|
// Optimized for most common case
|
||||||
|
var lineA = mappingA.generatedLine; |
||||||
|
var lineB = mappingB.generatedLine; |
||||||
|
var columnA = mappingA.generatedColumn; |
||||||
|
var columnB = mappingB.generatedColumn; |
||||||
|
return lineB > lineA || lineB == lineA && columnB >= columnA || |
||||||
|
util.compareByGeneratedPositionsInflated(mappingA, mappingB) <= 0; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* A data structure to provide a sorted view of accumulated mappings in a |
||||||
|
* performance conscious manner. It trades a neglibable overhead in general |
||||||
|
* case for a large speedup in case of mappings being added in order. |
||||||
|
*/ |
||||||
|
function MappingList() { |
||||||
|
this._array = []; |
||||||
|
this._sorted = true; |
||||||
|
// Serves as infimum
|
||||||
|
this._last = {generatedLine: -1, generatedColumn: 0}; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Iterate through internal items. This method takes the same arguments that |
||||||
|
* `Array.prototype.forEach` takes. |
||||||
|
* |
||||||
|
* NOTE: The order of the mappings is NOT guaranteed. |
||||||
|
*/ |
||||||
|
MappingList.prototype.unsortedForEach = |
||||||
|
function MappingList_forEach(aCallback, aThisArg) { |
||||||
|
this._array.forEach(aCallback, aThisArg); |
||||||
|
}; |
||||||
|
|
||||||
|
/** |
||||||
|
* Add the given source mapping. |
||||||
|
* |
||||||
|
* @param Object aMapping |
||||||
|
*/ |
||||||
|
MappingList.prototype.add = function MappingList_add(aMapping) { |
||||||
|
if (generatedPositionAfter(this._last, aMapping)) { |
||||||
|
this._last = aMapping; |
||||||
|
this._array.push(aMapping); |
||||||
|
} else { |
||||||
|
this._sorted = false; |
||||||
|
this._array.push(aMapping); |
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
/** |
||||||
|
* Returns the flat, sorted array of mappings. The mappings are sorted by |
||||||
|
* generated position. |
||||||
|
* |
||||||
|
* WARNING: This method returns internal data without copying, for |
||||||
|
* performance. The return value must NOT be mutated, and should be treated as |
||||||
|
* an immutable borrow. If you want to take ownership, you must make your own |
||||||
|
* copy. |
||||||
|
*/ |
||||||
|
MappingList.prototype.toArray = function MappingList_toArray() { |
||||||
|
if (!this._sorted) { |
||||||
|
this._array.sort(util.compareByGeneratedPositionsInflated); |
||||||
|
this._sorted = true; |
||||||
|
} |
||||||
|
return this._array; |
||||||
|
}; |
||||||
|
|
||||||
|
exports.MappingList = MappingList; |
@ -0,0 +1,114 @@ |
|||||||
|
/* -*- Mode: js; js-indent-level: 2; -*- */ |
||||||
|
/* |
||||||
|
* Copyright 2011 Mozilla Foundation and contributors |
||||||
|
* Licensed under the New BSD license. See LICENSE or: |
||||||
|
* http://opensource.org/licenses/BSD-3-Clause
|
||||||
|
*/ |
||||||
|
|
||||||
|
// It turns out that some (most?) JavaScript engines don't self-host
|
||||||
|
// `Array.prototype.sort`. This makes sense because C++ will likely remain
|
||||||
|
// faster than JS when doing raw CPU-intensive sorting. However, when using a
|
||||||
|
// custom comparator function, calling back and forth between the VM's C++ and
|
||||||
|
// JIT'd JS is rather slow *and* loses JIT type information, resulting in
|
||||||
|
// worse generated code for the comparator function than would be optimal. In
|
||||||
|
// fact, when sorting with a comparator, these costs outweigh the benefits of
|
||||||
|
// sorting in C++. By using our own JS-implemented Quick Sort (below), we get
|
||||||
|
// a ~3500ms mean speed-up in `bench/bench.html`.
|
||||||
|
|
||||||
|
/** |
||||||
|
* Swap the elements indexed by `x` and `y` in the array `ary`. |
||||||
|
* |
||||||
|
* @param {Array} ary |
||||||
|
* The array. |
||||||
|
* @param {Number} x |
||||||
|
* The index of the first item. |
||||||
|
* @param {Number} y |
||||||
|
* The index of the second item. |
||||||
|
*/ |
||||||
|
function swap(ary, x, y) { |
||||||
|
var temp = ary[x]; |
||||||
|
ary[x] = ary[y]; |
||||||
|
ary[y] = temp; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Returns a random integer within the range `low .. high` inclusive. |
||||||
|
* |
||||||
|
* @param {Number} low |
||||||
|
* The lower bound on the range. |
||||||
|
* @param {Number} high |
||||||
|
* The upper bound on the range. |
||||||
|
*/ |
||||||
|
function randomIntInRange(low, high) { |
||||||
|
return Math.round(low + (Math.random() * (high - low))); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* The Quick Sort algorithm. |
||||||
|
* |
||||||
|
* @param {Array} ary |
||||||
|
* An array to sort. |
||||||
|
* @param {function} comparator |
||||||
|
* Function to use to compare two items. |
||||||
|
* @param {Number} p |
||||||
|
* Start index of the array |
||||||
|
* @param {Number} r |
||||||
|
* End index of the array |
||||||
|
*/ |
||||||
|
function doQuickSort(ary, comparator, p, r) { |
||||||
|
// If our lower bound is less than our upper bound, we (1) partition the
|
||||||
|
// array into two pieces and (2) recurse on each half. If it is not, this is
|
||||||
|
// the empty array and our base case.
|
||||||
|
|
||||||
|
if (p < r) { |
||||||
|
// (1) Partitioning.
|
||||||
|
//
|
||||||
|
// The partitioning chooses a pivot between `p` and `r` and moves all
|
||||||
|
// elements that are less than or equal to the pivot to the before it, and
|
||||||
|
// all the elements that are greater than it after it. The effect is that
|
||||||
|
// once partition is done, the pivot is in the exact place it will be when
|
||||||
|
// the array is put in sorted order, and it will not need to be moved
|
||||||
|
// again. This runs in O(n) time.
|
||||||
|
|
||||||
|
// Always choose a random pivot so that an input array which is reverse
|
||||||
|
// sorted does not cause O(n^2) running time.
|
||||||
|
var pivotIndex = randomIntInRange(p, r); |
||||||
|
var i = p - 1; |
||||||
|
|
||||||
|
swap(ary, pivotIndex, r); |
||||||
|
var pivot = ary[r]; |
||||||
|
|
||||||
|
// Immediately after `j` is incremented in this loop, the following hold
|
||||||
|
// true:
|
||||||
|
//
|
||||||
|
// * Every element in `ary[p .. i]` is less than or equal to the pivot.
|
||||||
|
//
|
||||||
|
// * Every element in `ary[i+1 .. j-1]` is greater than the pivot.
|
||||||
|
for (var j = p; j < r; j++) { |
||||||
|
if (comparator(ary[j], pivot) <= 0) { |
||||||
|
i += 1; |
||||||
|
swap(ary, i, j); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
swap(ary, i + 1, j); |
||||||
|
var q = i + 1; |
||||||
|
|
||||||
|
// (2) Recurse on each half.
|
||||||
|
|
||||||
|
doQuickSort(ary, comparator, p, q - 1); |
||||||
|
doQuickSort(ary, comparator, q + 1, r); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Sort the given array in-place with the given comparator function. |
||||||
|
* |
||||||
|
* @param {Array} ary |
||||||
|
* An array to sort. |
||||||
|
* @param {function} comparator |
||||||
|
* Function to use to compare two items. |
||||||
|
*/ |
||||||
|
exports.quickSort = function (ary, comparator) { |
||||||
|
doQuickSort(ary, comparator, 0, ary.length - 1); |
||||||
|
}; |
@ -0,0 +1,425 @@ |
|||||||
|
/* -*- Mode: js; js-indent-level: 2; -*- */ |
||||||
|
/* |
||||||
|
* Copyright 2011 Mozilla Foundation and contributors |
||||||
|
* Licensed under the New BSD license. See LICENSE or: |
||||||
|
* http://opensource.org/licenses/BSD-3-Clause
|
||||||
|
*/ |
||||||
|
|
||||||
|
var base64VLQ = require('./base64-vlq'); |
||||||
|
var util = require('./util'); |
||||||
|
var ArraySet = require('./array-set').ArraySet; |
||||||
|
var MappingList = require('./mapping-list').MappingList; |
||||||
|
|
||||||
|
/** |
||||||
|
* An instance of the SourceMapGenerator represents a source map which is |
||||||
|
* being built incrementally. You may pass an object with the following |
||||||
|
* properties: |
||||||
|
* |
||||||
|
* - file: The filename of the generated source. |
||||||
|
* - sourceRoot: A root for all relative URLs in this source map. |
||||||
|
*/ |
||||||
|
function SourceMapGenerator(aArgs) { |
||||||
|
if (!aArgs) { |
||||||
|
aArgs = {}; |
||||||
|
} |
||||||
|
this._file = util.getArg(aArgs, 'file', null); |
||||||
|
this._sourceRoot = util.getArg(aArgs, 'sourceRoot', null); |
||||||
|
this._skipValidation = util.getArg(aArgs, 'skipValidation', false); |
||||||
|
this._sources = new ArraySet(); |
||||||
|
this._names = new ArraySet(); |
||||||
|
this._mappings = new MappingList(); |
||||||
|
this._sourcesContents = null; |
||||||
|
} |
||||||
|
|
||||||
|
SourceMapGenerator.prototype._version = 3; |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates a new SourceMapGenerator based on a SourceMapConsumer |
||||||
|
* |
||||||
|
* @param aSourceMapConsumer The SourceMap. |
||||||
|
*/ |
||||||
|
SourceMapGenerator.fromSourceMap = |
||||||
|
function SourceMapGenerator_fromSourceMap(aSourceMapConsumer) { |
||||||
|
var sourceRoot = aSourceMapConsumer.sourceRoot; |
||||||
|
var generator = new SourceMapGenerator({ |
||||||
|
file: aSourceMapConsumer.file, |
||||||
|
sourceRoot: sourceRoot |
||||||
|
}); |
||||||
|
aSourceMapConsumer.eachMapping(function (mapping) { |
||||||
|
var newMapping = { |
||||||
|
generated: { |
||||||
|
line: mapping.generatedLine, |
||||||
|
column: mapping.generatedColumn |
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
if (mapping.source != null) { |
||||||
|
newMapping.source = mapping.source; |
||||||
|
if (sourceRoot != null) { |
||||||
|
newMapping.source = util.relative(sourceRoot, newMapping.source); |
||||||
|
} |
||||||
|
|
||||||
|
newMapping.original = { |
||||||
|
line: mapping.originalLine, |
||||||
|
column: mapping.originalColumn |
||||||
|
}; |
||||||
|
|
||||||
|
if (mapping.name != null) { |
||||||
|
newMapping.name = mapping.name; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
generator.addMapping(newMapping); |
||||||
|
}); |
||||||
|
aSourceMapConsumer.sources.forEach(function (sourceFile) { |
||||||
|
var sourceRelative = sourceFile; |
||||||
|
if (sourceRoot !== null) { |
||||||
|
sourceRelative = util.relative(sourceRoot, sourceFile); |
||||||
|
} |
||||||
|
|
||||||
|
if (!generator._sources.has(sourceRelative)) { |
||||||
|
generator._sources.add(sourceRelative); |
||||||
|
} |
||||||
|
|
||||||
|
var content = aSourceMapConsumer.sourceContentFor(sourceFile); |
||||||
|
if (content != null) { |
||||||
|
generator.setSourceContent(sourceFile, content); |
||||||
|
} |
||||||
|
}); |
||||||
|
return generator; |
||||||
|
}; |
||||||
|
|
||||||
|
/** |
||||||
|
* Add a single mapping from original source line and column to the generated |
||||||
|
* source's line and column for this source map being created. The mapping |
||||||
|
* object should have the following properties: |
||||||
|
* |
||||||
|
* - generated: An object with the generated line and column positions. |
||||||
|
* - original: An object with the original line and column positions. |
||||||
|
* - source: The original source file (relative to the sourceRoot). |
||||||
|
* - name: An optional original token name for this mapping. |
||||||
|
*/ |
||||||
|
SourceMapGenerator.prototype.addMapping = |
||||||
|
function SourceMapGenerator_addMapping(aArgs) { |
||||||
|
var generated = util.getArg(aArgs, 'generated'); |
||||||
|
var original = util.getArg(aArgs, 'original', null); |
||||||
|
var source = util.getArg(aArgs, 'source', null); |
||||||
|
var name = util.getArg(aArgs, 'name', null); |
||||||
|
|
||||||
|
if (!this._skipValidation) { |
||||||
|
this._validateMapping(generated, original, source, name); |
||||||
|
} |
||||||
|
|
||||||
|
if (source != null) { |
||||||
|
source = String(source); |
||||||
|
if (!this._sources.has(source)) { |
||||||
|
this._sources.add(source); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
if (name != null) { |
||||||
|
name = String(name); |
||||||
|
if (!this._names.has(name)) { |
||||||
|
this._names.add(name); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
this._mappings.add({ |
||||||
|
generatedLine: generated.line, |
||||||
|
generatedColumn: generated.column, |
||||||
|
originalLine: original != null && original.line, |
||||||
|
originalColumn: original != null && original.column, |
||||||
|
source: source, |
||||||
|
name: name |
||||||
|
}); |
||||||
|
}; |
||||||
|
|
||||||
|
/** |
||||||
|
* Set the source content for a source file. |
||||||
|
*/ |
||||||
|
SourceMapGenerator.prototype.setSourceContent = |
||||||
|
function SourceMapGenerator_setSourceContent(aSourceFile, aSourceContent) { |
||||||
|
var source = aSourceFile; |
||||||
|
if (this._sourceRoot != null) { |
||||||
|
source = util.relative(this._sourceRoot, source); |
||||||
|
} |
||||||
|
|
||||||
|
if (aSourceContent != null) { |
||||||
|
// Add the source content to the _sourcesContents map.
|
||||||
|
// Create a new _sourcesContents map if the property is null.
|
||||||
|
if (!this._sourcesContents) { |
||||||
|
this._sourcesContents = Object.create(null); |
||||||
|
} |
||||||
|
this._sourcesContents[util.toSetString(source)] = aSourceContent; |
||||||
|
} else if (this._sourcesContents) { |
||||||
|
// Remove the source file from the _sourcesContents map.
|
||||||
|
// If the _sourcesContents map is empty, set the property to null.
|
||||||
|
delete this._sourcesContents[util.toSetString(source)]; |
||||||
|
if (Object.keys(this._sourcesContents).length === 0) { |
||||||
|
this._sourcesContents = null; |
||||||
|
} |
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
/** |
||||||
|
* Applies the mappings of a sub-source-map for a specific source file to the |
||||||
|
* source map being generated. Each mapping to the supplied source file is |
||||||
|
* rewritten using the supplied source map. Note: The resolution for the |
||||||
|
* resulting mappings is the minimium of this map and the supplied map. |
||||||
|
* |
||||||
|
* @param aSourceMapConsumer The source map to be applied. |
||||||
|
* @param aSourceFile Optional. The filename of the source file. |
||||||
|
* If omitted, SourceMapConsumer's file property will be used. |
||||||
|
* @param aSourceMapPath Optional. The dirname of the path to the source map |
||||||
|
* to be applied. If relative, it is relative to the SourceMapConsumer. |
||||||
|
* This parameter is needed when the two source maps aren't in the same |
||||||
|
* directory, and the source map to be applied contains relative source |
||||||
|
* paths. If so, those relative source paths need to be rewritten |
||||||
|
* relative to the SourceMapGenerator. |
||||||
|
*/ |
||||||
|
SourceMapGenerator.prototype.applySourceMap = |
||||||
|
function SourceMapGenerator_applySourceMap(aSourceMapConsumer, aSourceFile, aSourceMapPath) { |
||||||
|
var sourceFile = aSourceFile; |
||||||
|
// If aSourceFile is omitted, we will use the file property of the SourceMap
|
||||||
|
if (aSourceFile == null) { |
||||||
|
if (aSourceMapConsumer.file == null) { |
||||||
|
throw new Error( |
||||||
|
'SourceMapGenerator.prototype.applySourceMap requires either an explicit source file, ' + |
||||||
|
'or the source map\'s "file" property. Both were omitted.' |
||||||
|
); |
||||||
|
} |
||||||
|
sourceFile = aSourceMapConsumer.file; |
||||||
|
} |
||||||
|
var sourceRoot = this._sourceRoot; |
||||||
|
// Make "sourceFile" relative if an absolute Url is passed.
|
||||||
|
if (sourceRoot != null) { |
||||||
|
sourceFile = util.relative(sourceRoot, sourceFile); |
||||||
|
} |
||||||
|
// Applying the SourceMap can add and remove items from the sources and
|
||||||
|
// the names array.
|
||||||
|
var newSources = new ArraySet(); |
||||||
|
var newNames = new ArraySet(); |
||||||
|
|
||||||
|
// Find mappings for the "sourceFile"
|
||||||
|
this._mappings.unsortedForEach(function (mapping) { |
||||||
|
if (mapping.source === sourceFile && mapping.originalLine != null) { |
||||||
|
// Check if it can be mapped by the source map, then update the mapping.
|
||||||
|
var original = aSourceMapConsumer.originalPositionFor({ |
||||||
|
line: mapping.originalLine, |
||||||
|
column: mapping.originalColumn |
||||||
|
}); |
||||||
|
if (original.source != null) { |
||||||
|
// Copy mapping
|
||||||
|
mapping.source = original.source; |
||||||
|
if (aSourceMapPath != null) { |
||||||
|
mapping.source = util.join(aSourceMapPath, mapping.source) |
||||||
|
} |
||||||
|
if (sourceRoot != null) { |
||||||
|
mapping.source = util.relative(sourceRoot, mapping.source); |
||||||
|
} |
||||||
|
mapping.originalLine = original.line; |
||||||
|
mapping.originalColumn = original.column; |
||||||
|
if (original.name != null) { |
||||||
|
mapping.name = original.name; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
var source = mapping.source; |
||||||
|
if (source != null && !newSources.has(source)) { |
||||||
|
newSources.add(source); |
||||||
|
} |
||||||
|
|
||||||
|
var name = mapping.name; |
||||||
|
if (name != null && !newNames.has(name)) { |
||||||
|
newNames.add(name); |
||||||
|
} |
||||||
|
|
||||||
|
}, this); |
||||||
|
this._sources = newSources; |
||||||
|
this._names = newNames; |
||||||
|
|
||||||
|
// Copy sourcesContents of applied map.
|
||||||
|
aSourceMapConsumer.sources.forEach(function (sourceFile) { |
||||||
|
var content = aSourceMapConsumer.sourceContentFor(sourceFile); |
||||||
|
if (content != null) { |
||||||
|
if (aSourceMapPath != null) { |
||||||
|
sourceFile = util.join(aSourceMapPath, sourceFile); |
||||||
|
} |
||||||
|
if (sourceRoot != null) { |
||||||
|
sourceFile = util.relative(sourceRoot, sourceFile); |
||||||
|
} |
||||||
|
this.setSourceContent(sourceFile, content); |
||||||
|
} |
||||||
|
}, this); |
||||||
|
}; |
||||||
|
|
||||||
|
/** |
||||||
|
* A mapping can have one of the three levels of data: |
||||||
|
* |
||||||
|
* 1. Just the generated position. |
||||||
|
* 2. The Generated position, original position, and original source. |
||||||
|
* 3. Generated and original position, original source, as well as a name |
||||||
|
* token. |
||||||
|
* |
||||||
|
* To maintain consistency, we validate that any new mapping being added falls |
||||||
|
* in to one of these categories. |
||||||
|
*/ |
||||||
|
SourceMapGenerator.prototype._validateMapping = |
||||||
|
function SourceMapGenerator_validateMapping(aGenerated, aOriginal, aSource, |
||||||
|
aName) { |
||||||
|
// When aOriginal is truthy but has empty values for .line and .column,
|
||||||
|
// it is most likely a programmer error. In this case we throw a very
|
||||||
|
// specific error message to try to guide them the right way.
|
||||||
|
// For example: https://github.com/Polymer/polymer-bundler/pull/519
|
||||||
|
if (aOriginal && typeof aOriginal.line !== 'number' && typeof aOriginal.column !== 'number') { |
||||||
|
throw new Error( |
||||||
|
'original.line and original.column are not numbers -- you probably meant to omit ' + |
||||||
|
'the original mapping entirely and only map the generated position. If so, pass ' + |
||||||
|
'null for the original mapping instead of an object with empty or null values.' |
||||||
|
); |
||||||
|
} |
||||||
|
|
||||||
|
if (aGenerated && 'line' in aGenerated && 'column' in aGenerated |
||||||
|
&& aGenerated.line > 0 && aGenerated.column >= 0 |
||||||
|
&& !aOriginal && !aSource && !aName) { |
||||||
|
// Case 1.
|
||||||
|
return; |
||||||
|
} |
||||||
|
else if (aGenerated && 'line' in aGenerated && 'column' in aGenerated |
||||||
|
&& aOriginal && 'line' in aOriginal && 'column' in aOriginal |
||||||
|
&& aGenerated.line > 0 && aGenerated.column >= 0 |
||||||
|
&& aOriginal.line > 0 && aOriginal.column >= 0 |
||||||
|
&& aSource) { |
||||||
|
// Cases 2 and 3.
|
||||||
|
return; |
||||||
|
} |
||||||
|
else { |
||||||
|
throw new Error('Invalid mapping: ' + JSON.stringify({ |
||||||
|
generated: aGenerated, |
||||||
|
source: aSource, |
||||||
|
original: aOriginal, |
||||||
|
name: aName |
||||||
|
})); |
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
/** |
||||||
|
* Serialize the accumulated mappings in to the stream of base 64 VLQs |
||||||
|
* specified by the source map format. |
||||||
|
*/ |
||||||
|
SourceMapGenerator.prototype._serializeMappings = |
||||||
|
function SourceMapGenerator_serializeMappings() { |
||||||
|
var previousGeneratedColumn = 0; |
||||||
|
var previousGeneratedLine = 1; |
||||||
|
var previousOriginalColumn = 0; |
||||||
|
var previousOriginalLine = 0; |
||||||
|
var previousName = 0; |
||||||
|
var previousSource = 0; |
||||||
|
var result = ''; |
||||||
|
var next; |
||||||
|
var mapping; |
||||||
|
var nameIdx; |
||||||
|
var sourceIdx; |
||||||
|
|
||||||
|
var mappings = this._mappings.toArray(); |
||||||
|
for (var i = 0, len = mappings.length; i < len; i++) { |
||||||
|
mapping = mappings[i]; |
||||||
|
next = '' |
||||||
|
|
||||||
|
if (mapping.generatedLine !== previousGeneratedLine) { |
||||||
|
previousGeneratedColumn = 0; |
||||||
|
while (mapping.generatedLine !== previousGeneratedLine) { |
||||||
|
next += ';'; |
||||||
|
previousGeneratedLine++; |
||||||
|
} |
||||||
|
} |
||||||
|
else { |
||||||
|
if (i > 0) { |
||||||
|
if (!util.compareByGeneratedPositionsInflated(mapping, mappings[i - 1])) { |
||||||
|
continue; |
||||||
|
} |
||||||
|
next += ','; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
next += base64VLQ.encode(mapping.generatedColumn |
||||||
|
- previousGeneratedColumn); |
||||||
|
previousGeneratedColumn = mapping.generatedColumn; |
||||||
|
|
||||||
|
if (mapping.source != null) { |
||||||
|
sourceIdx = this._sources.indexOf(mapping.source); |
||||||
|
next += base64VLQ.encode(sourceIdx - previousSource); |
||||||
|
previousSource = sourceIdx; |
||||||
|
|
||||||
|
// lines are stored 0-based in SourceMap spec version 3
|
||||||
|
next += base64VLQ.encode(mapping.originalLine - 1 |
||||||
|
- previousOriginalLine); |
||||||
|
previousOriginalLine = mapping.originalLine - 1; |
||||||
|
|
||||||
|
next += base64VLQ.encode(mapping.originalColumn |
||||||
|
- previousOriginalColumn); |
||||||
|
previousOriginalColumn = mapping.originalColumn; |
||||||
|
|
||||||
|
if (mapping.name != null) { |
||||||
|
nameIdx = this._names.indexOf(mapping.name); |
||||||
|
next += base64VLQ.encode(nameIdx - previousName); |
||||||
|
previousName = nameIdx; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
result += next; |
||||||
|
} |
||||||
|
|
||||||
|
return result; |
||||||
|
}; |
||||||
|
|
||||||
|
SourceMapGenerator.prototype._generateSourcesContent = |
||||||
|
function SourceMapGenerator_generateSourcesContent(aSources, aSourceRoot) { |
||||||
|
return aSources.map(function (source) { |
||||||
|
if (!this._sourcesContents) { |
||||||
|
return null; |
||||||
|
} |
||||||
|
if (aSourceRoot != null) { |
||||||
|
source = util.relative(aSourceRoot, source); |
||||||
|
} |
||||||
|
var key = util.toSetString(source); |
||||||
|
return Object.prototype.hasOwnProperty.call(this._sourcesContents, key) |
||||||
|
? this._sourcesContents[key] |
||||||
|
: null; |
||||||
|
}, this); |
||||||
|
}; |
||||||
|
|
||||||
|
/** |
||||||
|
* Externalize the source map. |
||||||
|
*/ |
||||||
|
SourceMapGenerator.prototype.toJSON = |
||||||
|
function SourceMapGenerator_toJSON() { |
||||||
|
var map = { |
||||||
|
version: this._version, |
||||||
|
sources: this._sources.toArray(), |
||||||
|
names: this._names.toArray(), |
||||||
|
mappings: this._serializeMappings() |
||||||
|
}; |
||||||
|
if (this._file != null) { |
||||||
|
map.file = this._file; |
||||||
|
} |
||||||
|
if (this._sourceRoot != null) { |
||||||
|
map.sourceRoot = this._sourceRoot; |
||||||
|
} |
||||||
|
if (this._sourcesContents) { |
||||||
|
map.sourcesContent = this._generateSourcesContent(map.sources, map.sourceRoot); |
||||||
|
} |
||||||
|
|
||||||
|
return map; |
||||||
|
}; |
||||||
|
|
||||||
|
/** |
||||||
|
* Render the source map being generated to a string. |
||||||
|
*/ |
||||||
|
SourceMapGenerator.prototype.toString = |
||||||
|
function SourceMapGenerator_toString() { |
||||||
|
return JSON.stringify(this.toJSON()); |
||||||
|
}; |
||||||
|
|
||||||
|
exports.SourceMapGenerator = SourceMapGenerator; |
@ -0,0 +1,413 @@ |
|||||||
|
/* -*- Mode: js; js-indent-level: 2; -*- */ |
||||||
|
/* |
||||||
|
* Copyright 2011 Mozilla Foundation and contributors |
||||||
|
* Licensed under the New BSD license. See LICENSE or: |
||||||
|
* http://opensource.org/licenses/BSD-3-Clause
|
||||||
|
*/ |
||||||
|
|
||||||
|
var SourceMapGenerator = require('./source-map-generator').SourceMapGenerator; |
||||||
|
var util = require('./util'); |
||||||
|
|
||||||
|
// Matches a Windows-style `\r\n` newline or a `\n` newline used by all other
|
||||||
|
// operating systems these days (capturing the result).
|
||||||
|
var REGEX_NEWLINE = /(\r?\n)/; |
||||||
|
|
||||||
|
// Newline character code for charCodeAt() comparisons
|
||||||
|
var NEWLINE_CODE = 10; |
||||||
|
|
||||||
|
// Private symbol for identifying `SourceNode`s when multiple versions of
|
||||||
|
// the source-map library are loaded. This MUST NOT CHANGE across
|
||||||
|
// versions!
|
||||||
|
var isSourceNode = "$$$isSourceNode$$$"; |
||||||
|
|
||||||
|
/** |
||||||
|
* SourceNodes provide a way to abstract over interpolating/concatenating |
||||||
|
* snippets of generated JavaScript source code while maintaining the line and |
||||||
|
* column information associated with the original source code. |
||||||
|
* |
||||||
|
* @param aLine The original line number. |
||||||
|
* @param aColumn The original column number. |
||||||
|
* @param aSource The original source's filename. |
||||||
|
* @param aChunks Optional. An array of strings which are snippets of |
||||||
|
* generated JS, or other SourceNodes. |
||||||
|
* @param aName The original identifier. |
||||||
|
*/ |
||||||
|
function SourceNode(aLine, aColumn, aSource, aChunks, aName) { |
||||||
|
this.children = []; |
||||||
|
this.sourceContents = {}; |
||||||
|
this.line = aLine == null ? null : aLine; |
||||||
|
this.column = aColumn == null ? null : aColumn; |
||||||
|
this.source = aSource == null ? null : aSource; |
||||||
|
this.name = aName == null ? null : aName; |
||||||
|
this[isSourceNode] = true; |
||||||
|
if (aChunks != null) this.add(aChunks); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates a SourceNode from generated code and a SourceMapConsumer. |
||||||
|
* |
||||||
|
* @param aGeneratedCode The generated code |
||||||
|
* @param aSourceMapConsumer The SourceMap for the generated code |
||||||
|
* @param aRelativePath Optional. The path that relative sources in the |
||||||
|
* SourceMapConsumer should be relative to. |
||||||
|
*/ |
||||||
|
SourceNode.fromStringWithSourceMap = |
||||||
|
function SourceNode_fromStringWithSourceMap(aGeneratedCode, aSourceMapConsumer, aRelativePath) { |
||||||
|
// The SourceNode we want to fill with the generated code
|
||||||
|
// and the SourceMap
|
||||||
|
var node = new SourceNode(); |
||||||
|
|
||||||
|
// All even indices of this array are one line of the generated code,
|
||||||
|
// while all odd indices are the newlines between two adjacent lines
|
||||||
|
// (since `REGEX_NEWLINE` captures its match).
|
||||||
|
// Processed fragments are accessed by calling `shiftNextLine`.
|
||||||
|
var remainingLines = aGeneratedCode.split(REGEX_NEWLINE); |
||||||
|
var remainingLinesIndex = 0; |
||||||
|
var shiftNextLine = function() { |
||||||
|
var lineContents = getNextLine(); |
||||||
|
// The last line of a file might not have a newline.
|
||||||
|
var newLine = getNextLine() || ""; |
||||||
|
return lineContents + newLine; |
||||||
|
|
||||||
|
function getNextLine() { |
||||||
|
return remainingLinesIndex < remainingLines.length ? |
||||||
|
remainingLines[remainingLinesIndex++] : undefined; |
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
// We need to remember the position of "remainingLines"
|
||||||
|
var lastGeneratedLine = 1, lastGeneratedColumn = 0; |
||||||
|
|
||||||
|
// The generate SourceNodes we need a code range.
|
||||||
|
// To extract it current and last mapping is used.
|
||||||
|
// Here we store the last mapping.
|
||||||
|
var lastMapping = null; |
||||||
|
|
||||||
|
aSourceMapConsumer.eachMapping(function (mapping) { |
||||||
|
if (lastMapping !== null) { |
||||||
|
// We add the code from "lastMapping" to "mapping":
|
||||||
|
// First check if there is a new line in between.
|
||||||
|
if (lastGeneratedLine < mapping.generatedLine) { |
||||||
|
// Associate first line with "lastMapping"
|
||||||
|
addMappingWithCode(lastMapping, shiftNextLine()); |
||||||
|
lastGeneratedLine++; |
||||||
|
lastGeneratedColumn = 0; |
||||||
|
// The remaining code is added without mapping
|
||||||
|
} else { |
||||||
|
// There is no new line in between.
|
||||||
|
// Associate the code between "lastGeneratedColumn" and
|
||||||
|
// "mapping.generatedColumn" with "lastMapping"
|
||||||
|
var nextLine = remainingLines[remainingLinesIndex] || ''; |
||||||
|
var code = nextLine.substr(0, mapping.generatedColumn - |
||||||
|
lastGeneratedColumn); |
||||||
|
remainingLines[remainingLinesIndex] = nextLine.substr(mapping.generatedColumn - |
||||||
|
lastGeneratedColumn); |
||||||
|
lastGeneratedColumn = mapping.generatedColumn; |
||||||
|
addMappingWithCode(lastMapping, code); |
||||||
|
// No more remaining code, continue
|
||||||
|
lastMapping = mapping; |
||||||
|
return; |
||||||
|
} |
||||||
|
} |
||||||
|
// We add the generated code until the first mapping
|
||||||
|
// to the SourceNode without any mapping.
|
||||||
|
// Each line is added as separate string.
|
||||||
|
while (lastGeneratedLine < mapping.generatedLine) { |
||||||
|
node.add(shiftNextLine()); |
||||||
|
lastGeneratedLine++; |
||||||
|
} |
||||||
|
if (lastGeneratedColumn < mapping.generatedColumn) { |
||||||
|
var nextLine = remainingLines[remainingLinesIndex] || ''; |
||||||
|
node.add(nextLine.substr(0, mapping.generatedColumn)); |
||||||
|
remainingLines[remainingLinesIndex] = nextLine.substr(mapping.generatedColumn); |
||||||
|
lastGeneratedColumn = mapping.generatedColumn; |
||||||
|
} |
||||||
|
lastMapping = mapping; |
||||||
|
}, this); |
||||||
|
// We have processed all mappings.
|
||||||
|
if (remainingLinesIndex < remainingLines.length) { |
||||||
|
if (lastMapping) { |
||||||
|
// Associate the remaining code in the current line with "lastMapping"
|
||||||
|
addMappingWithCode(lastMapping, shiftNextLine()); |
||||||
|
} |
||||||
|
// and add the remaining lines without any mapping
|
||||||
|
node.add(remainingLines.splice(remainingLinesIndex).join("")); |
||||||
|
} |
||||||
|
|
||||||
|
// Copy sourcesContent into SourceNode
|
||||||
|
aSourceMapConsumer.sources.forEach(function (sourceFile) { |
||||||
|
var content = aSourceMapConsumer.sourceContentFor(sourceFile); |
||||||
|
if (content != null) { |
||||||
|
if (aRelativePath != null) { |
||||||
|
sourceFile = util.join(aRelativePath, sourceFile); |
||||||
|
} |
||||||
|
node.setSourceContent(sourceFile, content); |
||||||
|
} |
||||||
|
}); |
||||||
|
|
||||||
|
return node; |
||||||
|
|
||||||
|
function addMappingWithCode(mapping, code) { |
||||||
|
if (mapping === null || mapping.source === undefined) { |
||||||
|
node.add(code); |
||||||
|
} else { |
||||||
|
var source = aRelativePath |
||||||
|
? util.join(aRelativePath, mapping.source) |
||||||
|
: mapping.source; |
||||||
|
node.add(new SourceNode(mapping.originalLine, |
||||||
|
mapping.originalColumn, |
||||||
|
source, |
||||||
|
code, |
||||||
|
mapping.name)); |
||||||
|
} |
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
/** |
||||||
|
* Add a chunk of generated JS to this source node. |
||||||
|
* |
||||||
|
* @param aChunk A string snippet of generated JS code, another instance of |
||||||
|
* SourceNode, or an array where each member is one of those things. |
||||||
|
*/ |
||||||
|
SourceNode.prototype.add = function SourceNode_add(aChunk) { |
||||||
|
if (Array.isArray(aChunk)) { |
||||||
|
aChunk.forEach(function (chunk) { |
||||||
|
this.add(chunk); |
||||||
|
}, this); |
||||||
|
} |
||||||
|
else if (aChunk[isSourceNode] || typeof aChunk === "string") { |
||||||
|
if (aChunk) { |
||||||
|
this.children.push(aChunk); |
||||||
|
} |
||||||
|
} |
||||||
|
else { |
||||||
|
throw new TypeError( |
||||||
|
"Expected a SourceNode, string, or an array of SourceNodes and strings. Got " + aChunk |
||||||
|
); |
||||||
|
} |
||||||
|
return this; |
||||||
|
}; |
||||||
|
|
||||||
|
/** |
||||||
|
* Add a chunk of generated JS to the beginning of this source node. |
||||||
|
* |
||||||
|
* @param aChunk A string snippet of generated JS code, another instance of |
||||||
|
* SourceNode, or an array where each member is one of those things. |
||||||
|
*/ |
||||||
|
SourceNode.prototype.prepend = function SourceNode_prepend(aChunk) { |
||||||
|
if (Array.isArray(aChunk)) { |
||||||
|
for (var i = aChunk.length-1; i >= 0; i--) { |
||||||
|
this.prepend(aChunk[i]); |
||||||
|
} |
||||||
|
} |
||||||
|
else if (aChunk[isSourceNode] || typeof aChunk === "string") { |
||||||
|
this.children.unshift(aChunk); |
||||||
|
} |
||||||
|
else { |
||||||
|
throw new TypeError( |
||||||
|
"Expected a SourceNode, string, or an array of SourceNodes and strings. Got " + aChunk |
||||||
|
); |
||||||
|
} |
||||||
|
return this; |
||||||
|
}; |
||||||
|
|
||||||
|
/** |
||||||
|
* Walk over the tree of JS snippets in this node and its children. The |
||||||
|
* walking function is called once for each snippet of JS and is passed that |
||||||
|
* snippet and the its original associated source's line/column location. |
||||||
|
* |
||||||
|
* @param aFn The traversal function. |
||||||
|
*/ |
||||||
|
SourceNode.prototype.walk = function SourceNode_walk(aFn) { |
||||||
|
var chunk; |
||||||
|
for (var i = 0, len = this.children.length; i < len; i++) { |
||||||
|
chunk = this.children[i]; |
||||||
|
if (chunk[isSourceNode]) { |
||||||
|
chunk.walk(aFn); |
||||||
|
} |
||||||
|
else { |
||||||
|
if (chunk !== '') { |
||||||
|
aFn(chunk, { source: this.source, |
||||||
|
line: this.line, |
||||||
|
column: this.column, |
||||||
|
name: this.name }); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
/** |
||||||
|
* Like `String.prototype.join` except for SourceNodes. Inserts `aStr` between |
||||||
|
* each of `this.children`. |
||||||
|
* |
||||||
|
* @param aSep The separator. |
||||||
|
*/ |
||||||
|
SourceNode.prototype.join = function SourceNode_join(aSep) { |
||||||
|
var newChildren; |
||||||
|
var i; |
||||||
|
var len = this.children.length; |
||||||
|
if (len > 0) { |
||||||
|
newChildren = []; |
||||||
|
for (i = 0; i < len-1; i++) { |
||||||
|
newChildren.push(this.children[i]); |
||||||
|
newChildren.push(aSep); |
||||||
|
} |
||||||
|
newChildren.push(this.children[i]); |
||||||
|
this.children = newChildren; |
||||||
|
} |
||||||
|
return this; |
||||||
|
}; |
||||||
|
|
||||||
|
/** |
||||||
|
* Call String.prototype.replace on the very right-most source snippet. Useful |
||||||
|
* for trimming whitespace from the end of a source node, etc. |
||||||
|
* |
||||||
|
* @param aPattern The pattern to replace. |
||||||
|
* @param aReplacement The thing to replace the pattern with. |
||||||
|
*/ |
||||||
|
SourceNode.prototype.replaceRight = function SourceNode_replaceRight(aPattern, aReplacement) { |
||||||
|
var lastChild = this.children[this.children.length - 1]; |
||||||
|
if (lastChild[isSourceNode]) { |
||||||
|
lastChild.replaceRight(aPattern, aReplacement); |
||||||
|
} |
||||||
|
else if (typeof lastChild === 'string') { |
||||||
|
this.children[this.children.length - 1] = lastChild.replace(aPattern, aReplacement); |
||||||
|
} |
||||||
|
else { |
||||||
|
this.children.push(''.replace(aPattern, aReplacement)); |
||||||
|
} |
||||||
|
return this; |
||||||
|
}; |
||||||
|
|
||||||
|
/** |
||||||
|
* Set the source content for a source file. This will be added to the SourceMapGenerator |
||||||
|
* in the sourcesContent field. |
||||||
|
* |
||||||
|
* @param aSourceFile The filename of the source file |
||||||
|
* @param aSourceContent The content of the source file |
||||||
|
*/ |
||||||
|
SourceNode.prototype.setSourceContent = |
||||||
|
function SourceNode_setSourceContent(aSourceFile, aSourceContent) { |
||||||
|
this.sourceContents[util.toSetString(aSourceFile)] = aSourceContent; |
||||||
|
}; |
||||||
|
|
||||||
|
/** |
||||||
|
* Walk over the tree of SourceNodes. The walking function is called for each |
||||||
|
* source file content and is passed the filename and source content. |
||||||
|
* |
||||||
|
* @param aFn The traversal function. |
||||||
|
*/ |
||||||
|
SourceNode.prototype.walkSourceContents = |
||||||
|
function SourceNode_walkSourceContents(aFn) { |
||||||
|
for (var i = 0, len = this.children.length; i < len; i++) { |
||||||
|
if (this.children[i][isSourceNode]) { |
||||||
|
this.children[i].walkSourceContents(aFn); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
var sources = Object.keys(this.sourceContents); |
||||||
|
for (var i = 0, len = sources.length; i < len; i++) { |
||||||
|
aFn(util.fromSetString(sources[i]), this.sourceContents[sources[i]]); |
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
/** |
||||||
|
* Return the string representation of this source node. Walks over the tree |
||||||
|
* and concatenates all the various snippets together to one string. |
||||||
|
*/ |
||||||
|
SourceNode.prototype.toString = function SourceNode_toString() { |
||||||
|
var str = ""; |
||||||
|
this.walk(function (chunk) { |
||||||
|
str += chunk; |
||||||
|
}); |
||||||
|
return str; |
||||||
|
}; |
||||||
|
|
||||||
|
/** |
||||||
|
* Returns the string representation of this source node along with a source |
||||||
|
* map. |
||||||
|
*/ |
||||||
|
SourceNode.prototype.toStringWithSourceMap = function SourceNode_toStringWithSourceMap(aArgs) { |
||||||
|
var generated = { |
||||||
|
code: "", |
||||||
|
line: 1, |
||||||
|
column: 0 |
||||||
|
}; |
||||||
|
var map = new SourceMapGenerator(aArgs); |
||||||
|
var sourceMappingActive = false; |
||||||
|
var lastOriginalSource = null; |
||||||
|
var lastOriginalLine = null; |
||||||
|
var lastOriginalColumn = null; |
||||||
|
var lastOriginalName = null; |
||||||
|
this.walk(function (chunk, original) { |
||||||
|
generated.code += chunk; |
||||||
|
if (original.source !== null |
||||||
|
&& original.line !== null |
||||||
|
&& original.column !== null) { |
||||||
|
if(lastOriginalSource !== original.source |
||||||
|
|| lastOriginalLine !== original.line |
||||||
|
|| lastOriginalColumn !== original.column |
||||||
|
|| lastOriginalName !== original.name) { |
||||||
|
map.addMapping({ |
||||||
|
source: original.source, |
||||||
|
original: { |
||||||
|
line: original.line, |
||||||
|
column: original.column |
||||||
|
}, |
||||||
|
generated: { |
||||||
|
line: generated.line, |
||||||
|
column: generated.column |
||||||
|
}, |
||||||
|
name: original.name |
||||||
|
}); |
||||||
|
} |
||||||
|
lastOriginalSource = original.source; |
||||||
|
lastOriginalLine = original.line; |
||||||
|
lastOriginalColumn = original.column; |
||||||
|
lastOriginalName = original.name; |
||||||
|
sourceMappingActive = true; |
||||||
|
} else if (sourceMappingActive) { |
||||||
|
map.addMapping({ |
||||||
|
generated: { |
||||||
|
line: generated.line, |
||||||
|
column: generated.column |
||||||
|
} |
||||||
|
}); |
||||||
|
lastOriginalSource = null; |
||||||
|
sourceMappingActive = false; |
||||||
|
} |
||||||
|
for (var idx = 0, length = chunk.length; idx < length; idx++) { |
||||||
|
if (chunk.charCodeAt(idx) === NEWLINE_CODE) { |
||||||
|
generated.line++; |
||||||
|
generated.column = 0; |
||||||
|
// Mappings end at eol
|
||||||
|
if (idx + 1 === length) { |
||||||
|
lastOriginalSource = null; |
||||||
|
sourceMappingActive = false; |
||||||
|
} else if (sourceMappingActive) { |
||||||
|
map.addMapping({ |
||||||
|
source: original.source, |
||||||
|
original: { |
||||||
|
line: original.line, |
||||||
|
column: original.column |
||||||
|
}, |
||||||
|
generated: { |
||||||
|
line: generated.line, |
||||||
|
column: generated.column |
||||||
|
}, |
||||||
|
name: original.name |
||||||
|
}); |
||||||
|
} |
||||||
|
} else { |
||||||
|
generated.column++; |
||||||
|
} |
||||||
|
} |
||||||
|
}); |
||||||
|
this.walkSourceContents(function (sourceFile, sourceContent) { |
||||||
|
map.setSourceContent(sourceFile, sourceContent); |
||||||
|
}); |
||||||
|
|
||||||
|
return { code: generated.code, map: map }; |
||||||
|
}; |
||||||
|
|
||||||
|
exports.SourceNode = SourceNode; |
@ -0,0 +1,488 @@ |
|||||||
|
/* -*- Mode: js; js-indent-level: 2; -*- */ |
||||||
|
/* |
||||||
|
* Copyright 2011 Mozilla Foundation and contributors |
||||||
|
* Licensed under the New BSD license. See LICENSE or: |
||||||
|
* http://opensource.org/licenses/BSD-3-Clause
|
||||||
|
*/ |
||||||
|
|
||||||
|
/** |
||||||
|
* This is a helper function for getting values from parameter/options |
||||||
|
* objects. |
||||||
|
* |
||||||
|
* @param args The object we are extracting values from |
||||||
|
* @param name The name of the property we are getting. |
||||||
|
* @param defaultValue An optional value to return if the property is missing |
||||||
|
* from the object. If this is not specified and the property is missing, an |
||||||
|
* error will be thrown. |
||||||
|
*/ |
||||||
|
function getArg(aArgs, aName, aDefaultValue) { |
||||||
|
if (aName in aArgs) { |
||||||
|
return aArgs[aName]; |
||||||
|
} else if (arguments.length === 3) { |
||||||
|
return aDefaultValue; |
||||||
|
} else { |
||||||
|
throw new Error('"' + aName + '" is a required argument.'); |
||||||
|
} |
||||||
|
} |
||||||
|
exports.getArg = getArg; |
||||||
|
|
||||||
|
var urlRegexp = /^(?:([\w+\-.]+):)?\/\/(?:(\w+:\w+)@)?([\w.-]*)(?::(\d+))?(.*)$/; |
||||||
|
var dataUrlRegexp = /^data:.+\,.+$/; |
||||||
|
|
||||||
|
function urlParse(aUrl) { |
||||||
|
var match = aUrl.match(urlRegexp); |
||||||
|
if (!match) { |
||||||
|
return null; |
||||||
|
} |
||||||
|
return { |
||||||
|
scheme: match[1], |
||||||
|
auth: match[2], |
||||||
|
host: match[3], |
||||||
|
port: match[4], |
||||||
|
path: match[5] |
||||||
|
}; |
||||||
|
} |
||||||
|
exports.urlParse = urlParse; |
||||||
|
|
||||||
|
function urlGenerate(aParsedUrl) { |
||||||
|
var url = ''; |
||||||
|
if (aParsedUrl.scheme) { |
||||||
|
url += aParsedUrl.scheme + ':'; |
||||||
|
} |
||||||
|
url += '//'; |
||||||
|
if (aParsedUrl.auth) { |
||||||
|
url += aParsedUrl.auth + '@'; |
||||||
|
} |
||||||
|
if (aParsedUrl.host) { |
||||||
|
url += aParsedUrl.host; |
||||||
|
} |
||||||
|
if (aParsedUrl.port) { |
||||||
|
url += ":" + aParsedUrl.port |
||||||
|
} |
||||||
|
if (aParsedUrl.path) { |
||||||
|
url += aParsedUrl.path; |
||||||
|
} |
||||||
|
return url; |
||||||
|
} |
||||||
|
exports.urlGenerate = urlGenerate; |
||||||
|
|
||||||
|
/** |
||||||
|
* Normalizes a path, or the path portion of a URL: |
||||||
|
* |
||||||
|
* - Replaces consecutive slashes with one slash. |
||||||
|
* - Removes unnecessary '.' parts. |
||||||
|
* - Removes unnecessary '<dir>/..' parts. |
||||||
|
* |
||||||
|
* Based on code in the Node.js 'path' core module. |
||||||
|
* |
||||||
|
* @param aPath The path or url to normalize. |
||||||
|
*/ |
||||||
|
function normalize(aPath) { |
||||||
|
var path = aPath; |
||||||
|
var url = urlParse(aPath); |
||||||
|
if (url) { |
||||||
|
if (!url.path) { |
||||||
|
return aPath; |
||||||
|
} |
||||||
|
path = url.path; |
||||||
|
} |
||||||
|
var isAbsolute = exports.isAbsolute(path); |
||||||
|
|
||||||
|
var parts = path.split(/\/+/); |
||||||
|
for (var part, up = 0, i = parts.length - 1; i >= 0; i--) { |
||||||
|
part = parts[i]; |
||||||
|
if (part === '.') { |
||||||
|
parts.splice(i, 1); |
||||||
|
} else if (part === '..') { |
||||||
|
up++; |
||||||
|
} else if (up > 0) { |
||||||
|
if (part === '') { |
||||||
|
// The first part is blank if the path is absolute. Trying to go
|
||||||
|
// above the root is a no-op. Therefore we can remove all '..' parts
|
||||||
|
// directly after the root.
|
||||||
|
parts.splice(i + 1, up); |
||||||
|
up = 0; |
||||||
|
} else { |
||||||
|
parts.splice(i, 2); |
||||||
|
up--; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
path = parts.join('/'); |
||||||
|
|
||||||
|
if (path === '') { |
||||||
|
path = isAbsolute ? '/' : '.'; |
||||||
|
} |
||||||
|
|
||||||
|
if (url) { |
||||||
|
url.path = path; |
||||||
|
return urlGenerate(url); |
||||||
|
} |
||||||
|
return path; |
||||||
|
} |
||||||
|
exports.normalize = normalize; |
||||||
|
|
||||||
|
/** |
||||||
|
* Joins two paths/URLs. |
||||||
|
* |
||||||
|
* @param aRoot The root path or URL. |
||||||
|
* @param aPath The path or URL to be joined with the root. |
||||||
|
* |
||||||
|
* - If aPath is a URL or a data URI, aPath is returned, unless aPath is a |
||||||
|
* scheme-relative URL: Then the scheme of aRoot, if any, is prepended |
||||||
|
* first. |
||||||
|
* - Otherwise aPath is a path. If aRoot is a URL, then its path portion |
||||||
|
* is updated with the result and aRoot is returned. Otherwise the result |
||||||
|
* is returned. |
||||||
|
* - If aPath is absolute, the result is aPath. |
||||||
|
* - Otherwise the two paths are joined with a slash. |
||||||
|
* - Joining for example 'http://' and 'www.example.com' is also supported. |
||||||
|
*/ |
||||||
|
function join(aRoot, aPath) { |
||||||
|
if (aRoot === "") { |
||||||
|
aRoot = "."; |
||||||
|
} |
||||||
|
if (aPath === "") { |
||||||
|
aPath = "."; |
||||||
|
} |
||||||
|
var aPathUrl = urlParse(aPath); |
||||||
|
var aRootUrl = urlParse(aRoot); |
||||||
|
if (aRootUrl) { |
||||||
|
aRoot = aRootUrl.path || '/'; |
||||||
|
} |
||||||
|
|
||||||
|
// `join(foo, '//www.example.org')`
|
||||||
|
if (aPathUrl && !aPathUrl.scheme) { |
||||||
|
if (aRootUrl) { |
||||||
|
aPathUrl.scheme = aRootUrl.scheme; |
||||||
|
} |
||||||
|
return urlGenerate(aPathUrl); |
||||||
|
} |
||||||
|
|
||||||
|
if (aPathUrl || aPath.match(dataUrlRegexp)) { |
||||||
|
return aPath; |
||||||
|
} |
||||||
|
|
||||||
|
// `join('http://', 'www.example.com')`
|
||||||
|
if (aRootUrl && !aRootUrl.host && !aRootUrl.path) { |
||||||
|
aRootUrl.host = aPath; |
||||||
|
return urlGenerate(aRootUrl); |
||||||
|
} |
||||||
|
|
||||||
|
var joined = aPath.charAt(0) === '/' |
||||||
|
? aPath |
||||||
|
: normalize(aRoot.replace(/\/+$/, '') + '/' + aPath); |
||||||
|
|
||||||
|
if (aRootUrl) { |
||||||
|
aRootUrl.path = joined; |
||||||
|
return urlGenerate(aRootUrl); |
||||||
|
} |
||||||
|
return joined; |
||||||
|
} |
||||||
|
exports.join = join; |
||||||
|
|
||||||
|
exports.isAbsolute = function (aPath) { |
||||||
|
return aPath.charAt(0) === '/' || urlRegexp.test(aPath); |
||||||
|
}; |
||||||
|
|
||||||
|
/** |
||||||
|
* Make a path relative to a URL or another path. |
||||||
|
* |
||||||
|
* @param aRoot The root path or URL. |
||||||
|
* @param aPath The path or URL to be made relative to aRoot. |
||||||
|
*/ |
||||||
|
function relative(aRoot, aPath) { |
||||||
|
if (aRoot === "") { |
||||||
|
aRoot = "."; |
||||||
|
} |
||||||
|
|
||||||
|
aRoot = aRoot.replace(/\/$/, ''); |
||||||
|
|
||||||
|
// It is possible for the path to be above the root. In this case, simply
|
||||||
|
// checking whether the root is a prefix of the path won't work. Instead, we
|
||||||
|
// need to remove components from the root one by one, until either we find
|
||||||
|
// a prefix that fits, or we run out of components to remove.
|
||||||
|
var level = 0; |
||||||
|
while (aPath.indexOf(aRoot + '/') !== 0) { |
||||||
|
var index = aRoot.lastIndexOf("/"); |
||||||
|
if (index < 0) { |
||||||
|
return aPath; |
||||||
|
} |
||||||
|
|
||||||
|
// If the only part of the root that is left is the scheme (i.e. http://,
|
||||||
|
// file:///, etc.), one or more slashes (/), or simply nothing at all, we
|
||||||
|
// have exhausted all components, so the path is not relative to the root.
|
||||||
|
aRoot = aRoot.slice(0, index); |
||||||
|
if (aRoot.match(/^([^\/]+:\/)?\/*$/)) { |
||||||
|
return aPath; |
||||||
|
} |
||||||
|
|
||||||
|
++level; |
||||||
|
} |
||||||
|
|
||||||
|
// Make sure we add a "../" for each component we removed from the root.
|
||||||
|
return Array(level + 1).join("../") + aPath.substr(aRoot.length + 1); |
||||||
|
} |
||||||
|
exports.relative = relative; |
||||||
|
|
||||||
|
var supportsNullProto = (function () { |
||||||
|
var obj = Object.create(null); |
||||||
|
return !('__proto__' in obj); |
||||||
|
}()); |
||||||
|
|
||||||
|
function identity (s) { |
||||||
|
return s; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Because behavior goes wacky when you set `__proto__` on objects, we |
||||||
|
* have to prefix all the strings in our set with an arbitrary character. |
||||||
|
* |
||||||
|
* See https://github.com/mozilla/source-map/pull/31 and
|
||||||
|
* https://github.com/mozilla/source-map/issues/30
|
||||||
|
* |
||||||
|
* @param String aStr |
||||||
|
*/ |
||||||
|
function toSetString(aStr) { |
||||||
|
if (isProtoString(aStr)) { |
||||||
|
return '$' + aStr; |
||||||
|
} |
||||||
|
|
||||||
|
return aStr; |
||||||
|
} |
||||||
|
exports.toSetString = supportsNullProto ? identity : toSetString; |
||||||
|
|
||||||
|
function fromSetString(aStr) { |
||||||
|
if (isProtoString(aStr)) { |
||||||
|
return aStr.slice(1); |
||||||
|
} |
||||||
|
|
||||||
|
return aStr; |
||||||
|
} |
||||||
|
exports.fromSetString = supportsNullProto ? identity : fromSetString; |
||||||
|
|
||||||
|
function isProtoString(s) { |
||||||
|
if (!s) { |
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
var length = s.length; |
||||||
|
|
||||||
|
if (length < 9 /* "__proto__".length */) { |
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
if (s.charCodeAt(length - 1) !== 95 /* '_' */ || |
||||||
|
s.charCodeAt(length - 2) !== 95 /* '_' */ || |
||||||
|
s.charCodeAt(length - 3) !== 111 /* 'o' */ || |
||||||
|
s.charCodeAt(length - 4) !== 116 /* 't' */ || |
||||||
|
s.charCodeAt(length - 5) !== 111 /* 'o' */ || |
||||||
|
s.charCodeAt(length - 6) !== 114 /* 'r' */ || |
||||||
|
s.charCodeAt(length - 7) !== 112 /* 'p' */ || |
||||||
|
s.charCodeAt(length - 8) !== 95 /* '_' */ || |
||||||
|
s.charCodeAt(length - 9) !== 95 /* '_' */) { |
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
for (var i = length - 10; i >= 0; i--) { |
||||||
|
if (s.charCodeAt(i) !== 36 /* '$' */) { |
||||||
|
return false; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Comparator between two mappings where the original positions are compared. |
||||||
|
* |
||||||
|
* Optionally pass in `true` as `onlyCompareGenerated` to consider two |
||||||
|
* mappings with the same original source/line/column, but different generated |
||||||
|
* line and column the same. Useful when searching for a mapping with a |
||||||
|
* stubbed out mapping. |
||||||
|
*/ |
||||||
|
function compareByOriginalPositions(mappingA, mappingB, onlyCompareOriginal) { |
||||||
|
var cmp = strcmp(mappingA.source, mappingB.source); |
||||||
|
if (cmp !== 0) { |
||||||
|
return cmp; |
||||||
|
} |
||||||
|
|
||||||
|
cmp = mappingA.originalLine - mappingB.originalLine; |
||||||
|
if (cmp !== 0) { |
||||||
|
return cmp; |
||||||
|
} |
||||||
|
|
||||||
|
cmp = mappingA.originalColumn - mappingB.originalColumn; |
||||||
|
if (cmp !== 0 || onlyCompareOriginal) { |
||||||
|
return cmp; |
||||||
|
} |
||||||
|
|
||||||
|
cmp = mappingA.generatedColumn - mappingB.generatedColumn; |
||||||
|
if (cmp !== 0) { |
||||||
|
return cmp; |
||||||
|
} |
||||||
|
|
||||||
|
cmp = mappingA.generatedLine - mappingB.generatedLine; |
||||||
|
if (cmp !== 0) { |
||||||
|
return cmp; |
||||||
|
} |
||||||
|
|
||||||
|
return strcmp(mappingA.name, mappingB.name); |
||||||
|
} |
||||||
|
exports.compareByOriginalPositions = compareByOriginalPositions; |
||||||
|
|
||||||
|
/** |
||||||
|
* Comparator between two mappings with deflated source and name indices where |
||||||
|
* the generated positions are compared. |
||||||
|
* |
||||||
|
* Optionally pass in `true` as `onlyCompareGenerated` to consider two |
||||||
|
* mappings with the same generated line and column, but different |
||||||
|
* source/name/original line and column the same. Useful when searching for a |
||||||
|
* mapping with a stubbed out mapping. |
||||||
|
*/ |
||||||
|
function compareByGeneratedPositionsDeflated(mappingA, mappingB, onlyCompareGenerated) { |
||||||
|
var cmp = mappingA.generatedLine - mappingB.generatedLine; |
||||||
|
if (cmp !== 0) { |
||||||
|
return cmp; |
||||||
|
} |
||||||
|
|
||||||
|
cmp = mappingA.generatedColumn - mappingB.generatedColumn; |
||||||
|
if (cmp !== 0 || onlyCompareGenerated) { |
||||||
|
return cmp; |
||||||
|
} |
||||||
|
|
||||||
|
cmp = strcmp(mappingA.source, mappingB.source); |
||||||
|
if (cmp !== 0) { |
||||||
|
return cmp; |
||||||
|
} |
||||||
|
|
||||||
|
cmp = mappingA.originalLine - mappingB.originalLine; |
||||||
|
if (cmp !== 0) { |
||||||
|
return cmp; |
||||||
|
} |
||||||
|
|
||||||
|
cmp = mappingA.originalColumn - mappingB.originalColumn; |
||||||
|
if (cmp !== 0) { |
||||||
|
return cmp; |
||||||
|
} |
||||||
|
|
||||||
|
return strcmp(mappingA.name, mappingB.name); |
||||||
|
} |
||||||
|
exports.compareByGeneratedPositionsDeflated = compareByGeneratedPositionsDeflated; |
||||||
|
|
||||||
|
function strcmp(aStr1, aStr2) { |
||||||
|
if (aStr1 === aStr2) { |
||||||
|
return 0; |
||||||
|
} |
||||||
|
|
||||||
|
if (aStr1 === null) { |
||||||
|
return 1; // aStr2 !== null
|
||||||
|
} |
||||||
|
|
||||||
|
if (aStr2 === null) { |
||||||
|
return -1; // aStr1 !== null
|
||||||
|
} |
||||||
|
|
||||||
|
if (aStr1 > aStr2) { |
||||||
|
return 1; |
||||||
|
} |
||||||
|
|
||||||
|
return -1; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Comparator between two mappings with inflated source and name strings where |
||||||
|
* the generated positions are compared. |
||||||
|
*/ |
||||||
|
function compareByGeneratedPositionsInflated(mappingA, mappingB) { |
||||||
|
var cmp = mappingA.generatedLine - mappingB.generatedLine; |
||||||
|
if (cmp !== 0) { |
||||||
|
return cmp; |
||||||
|
} |
||||||
|
|
||||||
|
cmp = mappingA.generatedColumn - mappingB.generatedColumn; |
||||||
|
if (cmp !== 0) { |
||||||
|
return cmp; |
||||||
|
} |
||||||
|
|
||||||
|
cmp = strcmp(mappingA.source, mappingB.source); |
||||||
|
if (cmp !== 0) { |
||||||
|
return cmp; |
||||||
|
} |
||||||
|
|
||||||
|
cmp = mappingA.originalLine - mappingB.originalLine; |
||||||
|
if (cmp !== 0) { |
||||||
|
return cmp; |
||||||
|
} |
||||||
|
|
||||||
|
cmp = mappingA.originalColumn - mappingB.originalColumn; |
||||||
|
if (cmp !== 0) { |
||||||
|
return cmp; |
||||||
|
} |
||||||
|
|
||||||
|
return strcmp(mappingA.name, mappingB.name); |
||||||
|
} |
||||||
|
exports.compareByGeneratedPositionsInflated = compareByGeneratedPositionsInflated; |
||||||
|
|
||||||
|
/** |
||||||
|
* Strip any JSON XSSI avoidance prefix from the string (as documented |
||||||
|
* in the source maps specification), and then parse the string as |
||||||
|
* JSON. |
||||||
|
*/ |
||||||
|
function parseSourceMapInput(str) { |
||||||
|
return JSON.parse(str.replace(/^\)]}'[^\n]*\n/, '')); |
||||||
|
} |
||||||
|
exports.parseSourceMapInput = parseSourceMapInput; |
||||||
|
|
||||||
|
/** |
||||||
|
* Compute the URL of a source given the the source root, the source's |
||||||
|
* URL, and the source map's URL. |
||||||
|
*/ |
||||||
|
function computeSourceURL(sourceRoot, sourceURL, sourceMapURL) { |
||||||
|
sourceURL = sourceURL || ''; |
||||||
|
|
||||||
|
if (sourceRoot) { |
||||||
|
// This follows what Chrome does.
|
||||||
|
if (sourceRoot[sourceRoot.length - 1] !== '/' && sourceURL[0] !== '/') { |
||||||
|
sourceRoot += '/'; |
||||||
|
} |
||||||
|
// The spec says:
|
||||||
|
// Line 4: An optional source root, useful for relocating source
|
||||||
|
// files on a server or removing repeated values in the
|
||||||
|
// “sources” entry. This value is prepended to the individual
|
||||||
|
// entries in the “source” field.
|
||||||
|
sourceURL = sourceRoot + sourceURL; |
||||||
|
} |
||||||
|
|
||||||
|
// Historically, SourceMapConsumer did not take the sourceMapURL as
|
||||||
|
// a parameter. This mode is still somewhat supported, which is why
|
||||||
|
// this code block is conditional. However, it's preferable to pass
|
||||||
|
// the source map URL to SourceMapConsumer, so that this function
|
||||||
|
// can implement the source URL resolution algorithm as outlined in
|
||||||
|
// the spec. This block is basically the equivalent of:
|
||||||
|
// new URL(sourceURL, sourceMapURL).toString()
|
||||||
|
// ... except it avoids using URL, which wasn't available in the
|
||||||
|
// older releases of node still supported by this library.
|
||||||
|
//
|
||||||
|
// The spec says:
|
||||||
|
// If the sources are not absolute URLs after prepending of the
|
||||||
|
// “sourceRoot”, the sources are resolved relative to the
|
||||||
|
// SourceMap (like resolving script src in a html document).
|
||||||
|
if (sourceMapURL) { |
||||||
|
var parsed = urlParse(sourceMapURL); |
||||||
|
if (!parsed) { |
||||||
|
throw new Error("sourceMapURL could not be parsed"); |
||||||
|
} |
||||||
|
if (parsed.path) { |
||||||
|
// Strip the last path component, but keep the "/".
|
||||||
|
var index = parsed.path.lastIndexOf('/'); |
||||||
|
if (index >= 0) { |
||||||
|
parsed.path = parsed.path.substring(0, index + 1); |
||||||
|
} |
||||||
|
} |
||||||
|
sourceURL = join(urlGenerate(parsed), sourceURL); |
||||||
|
} |
||||||
|
|
||||||
|
return normalize(sourceURL); |
||||||
|
} |
||||||
|
exports.computeSourceURL = computeSourceURL; |
@ -0,0 +1,98 @@ |
|||||||
|
export interface StartOfSourceMap { |
||||||
|
file?: string; |
||||||
|
sourceRoot?: string; |
||||||
|
} |
||||||
|
|
||||||
|
export interface RawSourceMap extends StartOfSourceMap { |
||||||
|
version: string; |
||||||
|
sources: string[]; |
||||||
|
names: string[]; |
||||||
|
sourcesContent?: string[]; |
||||||
|
mappings: string; |
||||||
|
} |
||||||
|
|
||||||
|
export interface Position { |
||||||
|
line: number; |
||||||
|
column: number; |
||||||
|
} |
||||||
|
|
||||||
|
export interface LineRange extends Position { |
||||||
|
lastColumn: number; |
||||||
|
} |
||||||
|
|
||||||
|
export interface FindPosition extends Position { |
||||||
|
// SourceMapConsumer.GREATEST_LOWER_BOUND or SourceMapConsumer.LEAST_UPPER_BOUND
|
||||||
|
bias?: number; |
||||||
|
} |
||||||
|
|
||||||
|
export interface SourceFindPosition extends FindPosition { |
||||||
|
source: string; |
||||||
|
} |
||||||
|
|
||||||
|
export interface MappedPosition extends Position { |
||||||
|
source: string; |
||||||
|
name?: string; |
||||||
|
} |
||||||
|
|
||||||
|
export interface MappingItem { |
||||||
|
source: string; |
||||||
|
generatedLine: number; |
||||||
|
generatedColumn: number; |
||||||
|
originalLine: number; |
||||||
|
originalColumn: number; |
||||||
|
name: string; |
||||||
|
} |
||||||
|
|
||||||
|
export class SourceMapConsumer { |
||||||
|
static GENERATED_ORDER: number; |
||||||
|
static ORIGINAL_ORDER: number; |
||||||
|
|
||||||
|
static GREATEST_LOWER_BOUND: number; |
||||||
|
static LEAST_UPPER_BOUND: number; |
||||||
|
|
||||||
|
constructor(rawSourceMap: RawSourceMap); |
||||||
|
computeColumnSpans(): void; |
||||||
|
originalPositionFor(generatedPosition: FindPosition): MappedPosition; |
||||||
|
generatedPositionFor(originalPosition: SourceFindPosition): LineRange; |
||||||
|
allGeneratedPositionsFor(originalPosition: MappedPosition): Position[]; |
||||||
|
hasContentsOfAllSources(): boolean; |
||||||
|
sourceContentFor(source: string, returnNullOnMissing?: boolean): string; |
||||||
|
eachMapping(callback: (mapping: MappingItem) => void, context?: any, order?: number): void; |
||||||
|
} |
||||||
|
|
||||||
|
export interface Mapping { |
||||||
|
generated: Position; |
||||||
|
original: Position; |
||||||
|
source: string; |
||||||
|
name?: string; |
||||||
|
} |
||||||
|
|
||||||
|
export class SourceMapGenerator { |
||||||
|
constructor(startOfSourceMap?: StartOfSourceMap); |
||||||
|
static fromSourceMap(sourceMapConsumer: SourceMapConsumer): SourceMapGenerator; |
||||||
|
addMapping(mapping: Mapping): void; |
||||||
|
setSourceContent(sourceFile: string, sourceContent: string): void; |
||||||
|
applySourceMap(sourceMapConsumer: SourceMapConsumer, sourceFile?: string, sourceMapPath?: string): void; |
||||||
|
toString(): string; |
||||||
|
} |
||||||
|
|
||||||
|
export interface CodeWithSourceMap { |
||||||
|
code: string; |
||||||
|
map: SourceMapGenerator; |
||||||
|
} |
||||||
|
|
||||||
|
export class SourceNode { |
||||||
|
constructor(); |
||||||
|
constructor(line: number, column: number, source: string); |
||||||
|
constructor(line: number, column: number, source: string, chunk?: string, name?: string); |
||||||
|
static fromStringWithSourceMap(code: string, sourceMapConsumer: SourceMapConsumer, relativePath?: string): SourceNode; |
||||||
|
add(chunk: string): void; |
||||||
|
prepend(chunk: string): void; |
||||||
|
setSourceContent(sourceFile: string, sourceContent: string): void; |
||||||
|
walk(fn: (chunk: string, mapping: MappedPosition) => void): void; |
||||||
|
walkSourceContents(fn: (file: string, content: string) => void): void; |
||||||
|
join(sep: string): SourceNode; |
||||||
|
replaceRight(pattern: string, replacement: string): SourceNode; |
||||||
|
toString(): string; |
||||||
|
toStringWithSourceMap(startOfSourceMap?: StartOfSourceMap): CodeWithSourceMap; |
||||||
|
} |
@ -0,0 +1,8 @@ |
|||||||
|
/* |
||||||
|
* Copyright 2009-2011 Mozilla Foundation and contributors |
||||||
|
* Licensed under the New BSD license. See LICENSE.txt or: |
||||||
|
* http://opensource.org/licenses/BSD-3-Clause
|
||||||
|
*/ |
||||||
|
exports.SourceMapGenerator = require('./lib/source-map-generator').SourceMapGenerator; |
||||||
|
exports.SourceMapConsumer = require('./lib/source-map-consumer').SourceMapConsumer; |
||||||
|
exports.SourceNode = require('./lib/source-node').SourceNode; |
@ -0,0 +1,52 @@ |
|||||||
|
{ |
||||||
|
"name": "@gulp-sourcemaps/identity-map", |
||||||
|
"version": "1.0.2", |
||||||
|
"description": "Gulp plugin for generating an identity sourcemap for a file.", |
||||||
|
"author": "Gulp-sourcemaps Team", |
||||||
|
"contributors": [ |
||||||
|
"Blaine Bublitz <blaine.bublitz@gmail.com>" |
||||||
|
], |
||||||
|
"repository": "gulp-sourcemaps/identity-map", |
||||||
|
"license": "MIT", |
||||||
|
"engines": { |
||||||
|
"node": ">= 0.10" |
||||||
|
}, |
||||||
|
"main": "index.js", |
||||||
|
"files": [ |
||||||
|
"LICENSE", |
||||||
|
"index.js", |
||||||
|
"lib" |
||||||
|
], |
||||||
|
"scripts": { |
||||||
|
"lint": "eslint . && jscs index.js test/index.js lib/", |
||||||
|
"pretest": "npm run lint", |
||||||
|
"test": "mocha --async-only", |
||||||
|
"cover": "istanbul cover _mocha --report lcovonly", |
||||||
|
"coveralls": "npm run cover && istanbul-coveralls" |
||||||
|
}, |
||||||
|
"dependencies": { |
||||||
|
"acorn": "^5.0.3", |
||||||
|
"css": "^2.2.1", |
||||||
|
"normalize-path": "^2.1.1", |
||||||
|
"source-map": "^0.6.0", |
||||||
|
"through2": "^2.0.3" |
||||||
|
}, |
||||||
|
"devDependencies": { |
||||||
|
"eslint": "^1.7.3", |
||||||
|
"eslint-config-gulp": "^2.0.0", |
||||||
|
"expect": "^1.19.0", |
||||||
|
"istanbul": "^0.4.3", |
||||||
|
"istanbul-coveralls": "^1.0.3", |
||||||
|
"jscs": "^2.3.5", |
||||||
|
"jscs-preset-gulp": "^1.0.0", |
||||||
|
"mississippi": "^1.3.0", |
||||||
|
"mocha": "^2.4.5", |
||||||
|
"vinyl": "^2.0.1" |
||||||
|
}, |
||||||
|
"keywords": [ |
||||||
|
"sourcemap", |
||||||
|
"identity", |
||||||
|
"generate", |
||||||
|
"stream" |
||||||
|
] |
||||||
|
} |
@ -0,0 +1,21 @@ |
|||||||
|
The MIT License (MIT) |
||||||
|
|
||||||
|
Copyright (c) 2017 Blaine Bublitz <blaine.bublitz@gmail.com> |
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy |
||||||
|
of this software and associated documentation files (the "Software"), to deal |
||||||
|
in the Software without restriction, including without limitation the rights |
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
||||||
|
copies of the Software, and to permit persons to whom the Software is |
||||||
|
furnished to do so, subject to the following conditions: |
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all |
||||||
|
copies or substantial portions of the Software. |
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
||||||
|
SOFTWARE. |
@ -0,0 +1,52 @@ |
|||||||
|
# @gulp-sourcemaps/map-sources |
||||||
|
|
||||||
|
[![NPM version][npm-image]][npm-url] [![Downloads][downloads-image]][npm-url] [![Build Status][travis-image]][travis-url] [![AppVeyor Build Status][appveyor-image]][appveyor-url] [![Coveralls Status][coveralls-image]][coveralls-url] |
||||||
|
|
||||||
|
Gulp plugin for mapping sources of a sourcemap. |
||||||
|
|
||||||
|
## Example |
||||||
|
|
||||||
|
```js |
||||||
|
var mapSources = require('@gulp-sourcemaps/map-sources'); |
||||||
|
|
||||||
|
gulp.src(...) |
||||||
|
.pipe(sourcemaps.init()) |
||||||
|
.pipe(mapSources(function(sourcePath, file) { |
||||||
|
return '../' + sourcePath; |
||||||
|
})) |
||||||
|
.pipe(sourcemaps.write()) |
||||||
|
.pipe(gulp.dest(...)) |
||||||
|
``` |
||||||
|
|
||||||
|
## API |
||||||
|
|
||||||
|
### `mapSources(mapFn)` |
||||||
|
|
||||||
|
Takes a map function as the only argument. Returns an `objectMode` Transform stream. |
||||||
|
|
||||||
|
#### `mapFn(sourcePath, file)` |
||||||
|
|
||||||
|
The map function is called once per value of the `sources` array of a `sourceMap` attached to each [`Vinyl`][vinyl-url] object passed through the stream. The map function is called with the `sourcePath` string from the `sources` array and the `file` object it originated from. The return value replaces the original value in the array. |
||||||
|
|
||||||
|
If a `Vinyl` object doesn't have a `sourceMap` or `sourceMap.sources` property, the file is passed through the stream without having the `mapFn` called. |
||||||
|
|
||||||
|
All `sources` are normalized to use `/` instead of `\\` as path separators. |
||||||
|
|
||||||
|
## License |
||||||
|
|
||||||
|
MIT |
||||||
|
|
||||||
|
[vinyl-url]: https://github.com/gulpjs/vinyl |
||||||
|
|
||||||
|
[downloads-image]: http://img.shields.io/npm/dm/@gulp-sourcemaps/map-sources.svg |
||||||
|
[npm-url]: https://npmjs.org/package/@gulp-sourcemaps/map-sources |
||||||
|
[npm-image]: http://img.shields.io/npm/v/@gulp-sourcemaps/map-sources.svg |
||||||
|
|
||||||
|
[travis-url]: https://travis-ci.org/gulp-sourcemaps/map-sources |
||||||
|
[travis-image]: http://img.shields.io/travis/gulp-sourcemaps/map-sources.svg?label=travis-ci |
||||||
|
|
||||||
|
[appveyor-url]: https://ci.appveyor.com/project/phated/map-sources |
||||||
|
[appveyor-image]: https://img.shields.io/appveyor/ci/phated/map-sources.svg?label=appveyor |
||||||
|
|
||||||
|
[coveralls-url]: https://coveralls.io/r/gulp-sourcemaps/map-sources |
||||||
|
[coveralls-image]: http://img.shields.io/coveralls/gulp-sourcemaps/map-sources.svg |
@ -0,0 +1,30 @@ |
|||||||
|
'use strict'; |
||||||
|
|
||||||
|
var through = require('through2'); |
||||||
|
var normalize = require('normalize-path'); |
||||||
|
|
||||||
|
function mapSources(mapFn) { |
||||||
|
|
||||||
|
function transform(file, _, cb) { |
||||||
|
if (!file.sourceMap || !file.sourceMap.sources) { |
||||||
|
return cb(null, file); |
||||||
|
} |
||||||
|
|
||||||
|
function mapper(sourcePath) { |
||||||
|
var result = sourcePath; |
||||||
|
if (typeof mapFn === 'function') { |
||||||
|
result = mapFn(sourcePath, file); |
||||||
|
} |
||||||
|
|
||||||
|
return normalize(result); |
||||||
|
} |
||||||
|
|
||||||
|
file.sourceMap.sources = file.sourceMap.sources.map(mapper); |
||||||
|
|
||||||
|
cb(null, file); |
||||||
|
} |
||||||
|
|
||||||
|
return through.obj(transform); |
||||||
|
} |
||||||
|
|
||||||
|
module.exports = mapSources; |
@ -0,0 +1,21 @@ |
|||||||
|
The MIT License (MIT) |
||||||
|
|
||||||
|
Copyright (c) 2014-2017, Jon Schlinkert |
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy |
||||||
|
of this software and associated documentation files (the "Software"), to deal |
||||||
|
in the Software without restriction, including without limitation the rights |
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
||||||
|
copies of the Software, and to permit persons to whom the Software is |
||||||
|
furnished to do so, subject to the following conditions: |
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in |
||||||
|
all copies or substantial portions of the Software. |
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
||||||
|
THE SOFTWARE. |
@ -0,0 +1,92 @@ |
|||||||
|
# normalize-path [![NPM version](https://img.shields.io/npm/v/normalize-path.svg?style=flat)](https://www.npmjs.com/package/normalize-path) [![NPM monthly downloads](https://img.shields.io/npm/dm/normalize-path.svg?style=flat)](https://npmjs.org/package/normalize-path) [![NPM total downloads](https://img.shields.io/npm/dt/normalize-path.svg?style=flat)](https://npmjs.org/package/normalize-path) [![Linux Build Status](https://img.shields.io/travis/jonschlinkert/normalize-path.svg?style=flat&label=Travis)](https://travis-ci.org/jonschlinkert/normalize-path) |
||||||
|
|
||||||
|
> Normalize file path slashes to be unix-like forward slashes. Also condenses repeat slashes to a single slash and removes and trailing slashes unless disabled. |
||||||
|
|
||||||
|
## Install |
||||||
|
|
||||||
|
Install with [npm](https://www.npmjs.com/): |
||||||
|
|
||||||
|
```sh |
||||||
|
$ npm install --save normalize-path |
||||||
|
``` |
||||||
|
|
||||||
|
## Usage |
||||||
|
|
||||||
|
```js |
||||||
|
var normalize = require('normalize-path'); |
||||||
|
|
||||||
|
normalize('\\foo\\bar\\baz\\'); |
||||||
|
//=> '/foo/bar/baz' |
||||||
|
|
||||||
|
normalize('./foo/bar/baz/'); |
||||||
|
//=> './foo/bar/baz' |
||||||
|
``` |
||||||
|
|
||||||
|
Pass `false` as the last argument to **keep** trailing slashes: |
||||||
|
|
||||||
|
```js |
||||||
|
normalize('./foo/bar/baz/', false); |
||||||
|
//=> './foo/bar/baz/' |
||||||
|
|
||||||
|
normalize('foo\\bar\\baz\\', false); |
||||||
|
//=> 'foo/bar/baz/' |
||||||
|
``` |
||||||
|
|
||||||
|
## About |
||||||
|
|
||||||
|
### Related projects |
||||||
|
|
||||||
|
* [contains-path](https://www.npmjs.com/package/contains-path): Return true if a file path contains the given path. | [homepage](https://github.com/jonschlinkert/contains-path "Return true if a file path contains the given path.") |
||||||
|
* [ends-with](https://www.npmjs.com/package/ends-with): Returns `true` if the given `string` or `array` ends with `suffix` using strict equality for… [more](https://github.com/jonschlinkert/ends-with) | [homepage](https://github.com/jonschlinkert/ends-with "Returns `true` if the given `string` or `array` ends with `suffix` using strict equality for comparisons.") |
||||||
|
* [is-absolute](https://www.npmjs.com/package/is-absolute): Polyfill for node.js `path.isAbolute`. Returns true if a file path is absolute. | [homepage](https://github.com/jonschlinkert/is-absolute "Polyfill for node.js `path.isAbolute`. Returns true if a file path is absolute.") |
||||||
|
* [is-relative](https://www.npmjs.com/package/is-relative): Returns `true` if the path appears to be relative. | [homepage](https://github.com/jonschlinkert/is-relative "Returns `true` if the path appears to be relative.") |
||||||
|
* [parse-filepath](https://www.npmjs.com/package/parse-filepath): Pollyfill for node.js `path.parse`, parses a filepath into an object. | [homepage](https://github.com/jonschlinkert/parse-filepath "Pollyfill for node.js `path.parse`, parses a filepath into an object.") |
||||||
|
* [path-ends-with](https://www.npmjs.com/package/path-ends-with): Return `true` if a file path ends with the given string/suffix. | [homepage](https://github.com/jonschlinkert/path-ends-with "Return `true` if a file path ends with the given string/suffix.") |
||||||
|
* [path-segments](https://www.npmjs.com/package/path-segments): Get n specific segments of a file path, e.g. first 2, last 3, etc. | [homepage](https://github.com/jonschlinkert/path-segments "Get n specific segments of a file path, e.g. first 2, last 3, etc.") |
||||||
|
* [rewrite-ext](https://www.npmjs.com/package/rewrite-ext): Automatically re-write the destination extension of a filepath based on the source extension. e.g… [more](https://github.com/jonschlinkert/rewrite-ext) | [homepage](https://github.com/jonschlinkert/rewrite-ext "Automatically re-write the destination extension of a filepath based on the source extension. e.g `.coffee` => `.js`. This will only rename the ext, no other path parts are modified.") |
||||||
|
* [unixify](https://www.npmjs.com/package/unixify): Convert Windows file paths to unix paths. | [homepage](https://github.com/jonschlinkert/unixify "Convert Windows file paths to unix paths.") |
||||||
|
|
||||||
|
### Contributing |
||||||
|
|
||||||
|
Pull requests and stars are always welcome. For bugs and feature requests, [please create an issue](../../issues/new). |
||||||
|
|
||||||
|
### Contributors |
||||||
|
|
||||||
|
| **Commits** | **Contributor** | |
||||||
|
| --- | --- | |
||||||
|
| 31 | [jonschlinkert](https://github.com/jonschlinkert) | |
||||||
|
| 1 | [phated](https://github.com/phated) | |
||||||
|
|
||||||
|
### Building docs |
||||||
|
|
||||||
|
_(This project's readme.md is generated by [verb](https://github.com/verbose/verb-generate-readme), please don't edit the readme directly. Any changes to the readme must be made in the [.verb.md](.verb.md) readme template.)_ |
||||||
|
|
||||||
|
To generate the readme, run the following command: |
||||||
|
|
||||||
|
```sh |
||||||
|
$ npm install -g verbose/verb#dev verb-generate-readme && verb |
||||||
|
``` |
||||||
|
|
||||||
|
### Running tests |
||||||
|
|
||||||
|
Running and reviewing unit tests is a great way to get familiarized with a library and its API. You can install dependencies and run tests with the following command: |
||||||
|
|
||||||
|
```sh |
||||||
|
$ npm install && npm test |
||||||
|
``` |
||||||
|
|
||||||
|
### Author |
||||||
|
|
||||||
|
**Jon Schlinkert** |
||||||
|
|
||||||
|
* [github/jonschlinkert](https://github.com/jonschlinkert) |
||||||
|
* [twitter/jonschlinkert](https://twitter.com/jonschlinkert) |
||||||
|
|
||||||
|
### License |
||||||
|
|
||||||
|
Copyright © 2017, [Jon Schlinkert](https://github.com/jonschlinkert). |
||||||
|
Released under the [MIT License](LICENSE). |
||||||
|
|
||||||
|
*** |
||||||
|
|
||||||
|
_This file was generated by [verb-generate-readme](https://github.com/verbose/verb-generate-readme), v0.4.3, on March 29, 2017._ |
@ -0,0 +1,19 @@ |
|||||||
|
/*! |
||||||
|
* normalize-path <https://github.com/jonschlinkert/normalize-path>
|
||||||
|
* |
||||||
|
* Copyright (c) 2014-2017, Jon Schlinkert. |
||||||
|
* Released under the MIT License. |
||||||
|
*/ |
||||||
|
|
||||||
|
var removeTrailingSeparator = require('remove-trailing-separator'); |
||||||
|
|
||||||
|
module.exports = function normalizePath(str, stripTrailing) { |
||||||
|
if (typeof str !== 'string') { |
||||||
|
throw new TypeError('expected a string'); |
||||||
|
} |
||||||
|
str = str.replace(/[\\\/]+/g, '/'); |
||||||
|
if (stripTrailing !== false) { |
||||||
|
str = removeTrailingSeparator(str); |
||||||
|
} |
||||||
|
return str; |
||||||
|
}; |