fix: prevent asset conflicts between React and Grid.js versions

Add coexistence checks to all enqueue methods to prevent loading
both React and Grid.js assets simultaneously.

Changes:
- ReactAdmin.php: Only enqueue React assets when ?react=1
- Init.php: Skip Grid.js when React active on admin pages
- Form.php, Coupon.php, Access.php: Restore classic assets when ?react=0
- Customer.php, Product.php, License.php: Add coexistence checks

Now the toggle between Classic and React versions works correctly.

Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
dwindown
2026-04-18 17:02:14 +07:00
parent bd9cdac02e
commit e8fbfb14c1
74973 changed files with 6658406 additions and 71 deletions

13
node_modules/gradient-parser/.editorconfig generated vendored Normal file
View File

@@ -0,0 +1,13 @@
# http://editorconfig.org
root = true
[*]
indent_style = space
indent_size = 2
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
[*.md]
trim_trailing_whitespace = false

13
node_modules/gradient-parser/.npmignore generated vendored Normal file
View File

@@ -0,0 +1,13 @@
node_modules/
npm-debug.log
bower_components/
coverage/
.idea/
.DS_Store
.DS_Store?
._*
.Trashes
Icon?
ehthumbs.db
Thumbs.db
.tmp

34
node_modules/gradient-parser/.travis.yml generated vendored Normal file
View File

@@ -0,0 +1,34 @@
language: node_js
node_js:
- '0.10'
before_script:
#- npm install -g codeclimate-test-reporter
after_script:
#TODO: enable publishing code coverage reports
#- codeclimate < test/coverage/**/lcov.info
notifications:
# publish build status to IRC channel: #gradient-parser
irc:
channels:
- chat.freenode.net#gradient-parser
on_success: always
on_failure: always
template:
- '%{repository}#%{build_number} (%{branch} - %{commit} : %{author}): %{message}'
- 'Change view : %{compare_url}'
- 'Build details : %{build_url}'
#TODO: enable publishing build status to gitter.im
# publish build status to gitter chat room: https://gitter.im/rafaelcaricio/gradient-parser
#webhooks:
# urls:
# - [REPLACE WITH YOUR WEBHOOK URL; https://webhooks.gitter.im/e/XXXXXXXXXXXXXXXX]
# on_success: always
# on_failure: always
# on_start: false
env:
#- CODECLIMATE_REPO_TOKEN=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

16
node_modules/gradient-parser/.umd generated vendored Normal file
View File

@@ -0,0 +1,16 @@
(function (window, factory) {
'use strict';
if (typeof define === 'function' && define.amd) {
// AMD
define([], factory);
} else if (typeof exports === 'object') {
// Node.js
module.exports = factory();
} else {
// Browser
window.gradientParser = factory();
}
}(this, function factory() {
// public API
return $1;
}));

21
node_modules/gradient-parser/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2014 Rafael Carício
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.

2
node_modules/gradient-parser/Makefile generated vendored Normal file
View File

@@ -0,0 +1,2 @@
all:
python -m SimpleHTTPServer 3000

152
node_modules/gradient-parser/README.md generated vendored Normal file
View File

@@ -0,0 +1,152 @@
# Gradient Parser
## About
Parse CSS3 gradient definition and returns AST `object`.
## Examples
```JavaScript
var gradient = require('gradient-parser');
var obj = gradient.parse('linear-gradient(30deg, #000, transparent)');
console.log(JSON.stringify(obj, null, 2));
```
Results in:
```JSON
[
{
"type": "linear-gradient",
"orientation": {
"type": "angular",
"value": "30"
},
"colorStops": [
{
"type": "hex",
"value": "000"
},
{
"type": "literal",
"value": "transparent"
}
]
}
]
```
## Install Choices
- `bower install gradient-parser`
- [download the zip](https://github.com/rafaelcaricio/gradient-parser/archive/master.zip)
## API
### gradient.parse
Accepts the gradient definitions as it is declared in `background-image` and returns an AST `object`.
## AST
### Common properties
All nodes have the following properties.
#### type
`String`. The possible values are the ones listed in the Types section bellow.
### Types
The available values of `node.type` are listed below, as well as the available properties of each node (other than the common properties listed above).
### linear-gradient
- orientation: `Object` possible types `directional` or `angular`.
- colorStops: `Array` of color stops of type `literal`, `hex`, `rgb`, or `rgba`.
### repeating-linear-gradient
- orientation: `Object` possible types `directional` or `angular`.
- colorStops: `Array` of color stops of type `literal`, `hex`, `rgb`, or `rgba`.
### radial-gradient
- orientation: `Array` or `undefined`. `Array` of possible types `shape`, `default-radial`.
- colorStops: `Array` of color stops of type `literal`, `hex`, `rgb`, or `rgba`.
### repeating-radial-gradient
- orientation: `Array` or `undefined`. `Array` of possible types `shape`, `default-radial`.
- colorStops: `Array` of color stops of type `literal`, `hex`, `rgb`, or `rgba`.
### directional
- value: `String` possible values `left`, `top`, `bottom`, or `right`.
### angular
- value: `Number` integer number.
### literal
- value: `String` literal name of the color.
### hex
- value: `String` hex value.
### rgb
- value: `Array` of length 3 of `Number`'s.
### rgba
- value: `Array` of length 4 or `Number`'s.
### shape
- style: `Object` or `undefined` possible types `extent-keyword`, `px`, `em`, `%`, or `positioning-keyword`.
- value: `String` possible values `ellipse` or `circle`.
- at: `Object` of attributes:
- x: `Object` possible types `extent-keyword`, `px`, `em`, `%`, or `positioning-keyword`.
- y: `Object` possible types `extent-keyword`, `px`, `em`, `%`, or `positioning-keyword`.
### default-radial
- at: `Object` of attributes:
- x: `Object` possible types `extent-keyword`, `px`, `em`, `%`, or `positioning-keyword`.
- y: `Object` possible types `extent-keyword`, `px`, `em`, `%`, or `positioning-keyword`.
### positioning-keyword
- value: `String` possible values `center`, `left`, `top`, `bottom`, or `right`.
### extent-keyword
- value: `String` possible values `closest-side`, `closest-corner`, `farthest-side`, `farthest-corner`, `contain`, or `cover`.
## License
(The MIT License)
Copyright (c) 2014 Rafael Caricio rafael@caricio.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.

31
node_modules/gradient-parser/bower.json generated vendored Normal file
View File

@@ -0,0 +1,31 @@
{
"name": "gradient-parser",
"version": "0.1.5",
"main": "build/web.js",
"ignore": [
".editorconfig",
".gitattributes",
".gitignore",
".jshintrc",
".npmignore",
".travis.yml",
".umd",
"gulpfile.js",
"npm-shrinkwrap.json",
"package.json",
"index.html",
"Makefile",
"build/node.js",
"README.md",
"gruntfile.js",
"lib/*",
"spec/*",
"LICENSE"
],
"dependencies": {
},
"devDependencies": {
}
}

339
node_modules/gradient-parser/build/node.js generated vendored Normal file
View File

@@ -0,0 +1,339 @@
// Copyright (c) 2014 Rafael Caricio. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
var GradientParser = {};
GradientParser.parse = (function() {
var tokens = {
linearGradient: /^(\-(webkit|o|ms|moz)\-)?(linear\-gradient)/i,
repeatingLinearGradient: /^(\-(webkit|o|ms|moz)\-)?(repeating\-linear\-gradient)/i,
radialGradient: /^(\-(webkit|o|ms|moz)\-)?(radial\-gradient)/i,
repeatingRadialGradient: /^(\-(webkit|o|ms|moz)\-)?(repeating\-radial\-gradient)/i,
sideOrCorner: /^to (left (top|bottom)|right (top|bottom)|left|right|top|bottom)/i,
extentKeywords: /^(closest\-side|closest\-corner|farthest\-side|farthest\-corner|contain|cover)/,
positionKeywords: /^(left|center|right|top|bottom)/i,
pixelValue: /^(-?(([0-9]*\.[0-9]+)|([0-9]+\.?)))px/,
percentageValue: /^(-?(([0-9]*\.[0-9]+)|([0-9]+\.?)))\%/,
emValue: /^(-?(([0-9]*\.[0-9]+)|([0-9]+\.?)))em/,
angleValue: /^(-?(([0-9]*\.[0-9]+)|([0-9]+\.?)))deg/,
startCall: /^\(/,
endCall: /^\)/,
comma: /^,/,
hexColor: /^\#([0-9a-fA-F]+)/,
literalColor: /^([a-zA-Z]+)/,
rgbColor: /^rgb/i,
rgbaColor: /^rgba/i,
number: /^(([0-9]*\.[0-9]+)|([0-9]+\.?))/
};
var input = '';
function error(msg) {
var err = new Error(input + ': ' + msg);
err.source = input;
throw err;
}
function getAST() {
var ast = matchListDefinitions();
if (input.length > 0) {
error('Invalid input not EOF');
}
return ast;
}
function matchListDefinitions() {
return matchListing(matchDefinition);
}
function matchDefinition() {
return matchGradient(
'linear-gradient',
tokens.linearGradient,
matchLinearOrientation) ||
matchGradient(
'repeating-linear-gradient',
tokens.repeatingLinearGradient,
matchLinearOrientation) ||
matchGradient(
'radial-gradient',
tokens.radialGradient,
matchListRadialOrientations) ||
matchGradient(
'repeating-radial-gradient',
tokens.repeatingRadialGradient,
matchListRadialOrientations);
}
function matchGradient(gradientType, pattern, orientationMatcher) {
return matchCall(pattern, function(captures) {
var orientation = orientationMatcher();
if (orientation) {
if (!scan(tokens.comma)) {
error('Missing comma before color stops');
}
}
return {
type: gradientType,
orientation: orientation,
colorStops: matchListing(matchColorStop)
};
});
}
function matchCall(pattern, callback) {
var captures = scan(pattern);
if (captures) {
if (!scan(tokens.startCall)) {
error('Missing (');
}
result = callback(captures);
if (!scan(tokens.endCall)) {
error('Missing )');
}
return result;
}
}
function matchLinearOrientation() {
return matchSideOrCorner() ||
matchAngle();
}
function matchSideOrCorner() {
return match('directional', tokens.sideOrCorner, 1);
}
function matchAngle() {
return match('angular', tokens.angleValue, 1);
}
function matchListRadialOrientations() {
var radialOrientations,
radialOrientation = matchRadialOrientation(),
lookaheadCache;
if (radialOrientation) {
radialOrientations = [];
radialOrientations.push(radialOrientation);
lookaheadCache = input;
if (scan(tokens.comma)) {
radialOrientation = matchRadialOrientation();
if (radialOrientation) {
radialOrientations.push(radialOrientation);
} else {
input = lookaheadCache;
}
}
}
return radialOrientations;
}
function matchRadialOrientation() {
var radialType = matchCircle() ||
matchEllipse();
if (radialType) {
radialType.at = matchAtPosition();
} else {
var defaultPosition = matchPositioning();
if (defaultPosition) {
radialType = {
type: 'default-radial',
at: defaultPosition
};
}
}
return radialType;
}
function matchCircle() {
var circle = match('shape', /^(circle)/i, 0);
if (circle) {
circle.style = matchLength() || matchExtentKeyword();
}
return circle;
}
function matchEllipse() {
var ellipse = match('shape', /^(ellipse)/i, 0);
if (ellipse) {
ellipse.style = matchDistance() || matchExtentKeyword();
}
return ellipse;
}
function matchExtentKeyword() {
return match('extent-keyword', tokens.extentKeywords, 1);
}
function matchAtPosition() {
if (match('position', /^at/, 0)) {
var positioning = matchPositioning();
if (!positioning) {
error('Missing positioning value');
}
return positioning;
}
}
function matchPositioning() {
var location = matchCoordinates();
if (location.x || location.y) {
return {
type: 'position',
value: location
};
}
}
function matchCoordinates() {
return {
x: matchDistance(),
y: matchDistance()
};
}
function matchListing(matcher) {
var captures = matcher(),
result = [];
if (captures) {
result.push(captures);
while (scan(tokens.comma)) {
captures = matcher();
if (captures) {
result.push(captures);
} else {
error('One extra comma');
}
}
}
return result;
}
function matchColorStop() {
var color = matchColor();
if (!color) {
error('Expected color definition');
}
color.length = matchDistance();
return color;
}
function matchColor() {
return matchHexColor() ||
matchRGBAColor() ||
matchRGBColor() ||
matchLiteralColor();
}
function matchLiteralColor() {
return match('literal', tokens.literalColor, 0);
}
function matchHexColor() {
return match('hex', tokens.hexColor, 1);
}
function matchRGBColor() {
return matchCall(tokens.rgbColor, function() {
return {
type: 'rgb',
value: matchListing(matchNumber)
};
});
}
function matchRGBAColor() {
return matchCall(tokens.rgbaColor, function() {
return {
type: 'rgba',
value: matchListing(matchNumber)
};
});
}
function matchNumber() {
return scan(tokens.number)[1];
}
function matchDistance() {
return match('%', tokens.percentageValue, 1) ||
matchPositionKeyword() ||
matchLength();
}
function matchPositionKeyword() {
return match('position-keyword', tokens.positionKeywords, 1);
}
function matchLength() {
return match('px', tokens.pixelValue, 1) ||
match('em', tokens.emValue, 1);
}
function match(type, pattern, captureIndex) {
var captures = scan(pattern);
if (captures) {
return {
type: type,
value: captures[captureIndex]
};
}
}
function scan(regexp) {
var captures,
blankCaptures;
blankCaptures = /^[\n\r\t\s]+/.exec(input);
if (blankCaptures) {
consume(blankCaptures[0].length);
}
captures = regexp.exec(input);
if (captures) {
consume(captures[0].length);
}
return captures;
}
function consume(size) {
input = input.substr(size);
}
return function(code) {
input = code.toString();
return getAST();
};
})();
exports.parse = (GradientParser || {}).parse;

337
node_modules/gradient-parser/build/web.js generated vendored Normal file
View File

@@ -0,0 +1,337 @@
// Copyright (c) 2014 Rafael Caricio. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
var GradientParser = {};
GradientParser.parse = (function() {
var tokens = {
linearGradient: /^(\-(webkit|o|ms|moz)\-)?(linear\-gradient)/i,
repeatingLinearGradient: /^(\-(webkit|o|ms|moz)\-)?(repeating\-linear\-gradient)/i,
radialGradient: /^(\-(webkit|o|ms|moz)\-)?(radial\-gradient)/i,
repeatingRadialGradient: /^(\-(webkit|o|ms|moz)\-)?(repeating\-radial\-gradient)/i,
sideOrCorner: /^to (left (top|bottom)|right (top|bottom)|left|right|top|bottom)/i,
extentKeywords: /^(closest\-side|closest\-corner|farthest\-side|farthest\-corner|contain|cover)/,
positionKeywords: /^(left|center|right|top|bottom)/i,
pixelValue: /^(-?(([0-9]*\.[0-9]+)|([0-9]+\.?)))px/,
percentageValue: /^(-?(([0-9]*\.[0-9]+)|([0-9]+\.?)))\%/,
emValue: /^(-?(([0-9]*\.[0-9]+)|([0-9]+\.?)))em/,
angleValue: /^(-?(([0-9]*\.[0-9]+)|([0-9]+\.?)))deg/,
startCall: /^\(/,
endCall: /^\)/,
comma: /^,/,
hexColor: /^\#([0-9a-fA-F]+)/,
literalColor: /^([a-zA-Z]+)/,
rgbColor: /^rgb/i,
rgbaColor: /^rgba/i,
number: /^(([0-9]*\.[0-9]+)|([0-9]+\.?))/
};
var input = '';
function error(msg) {
var err = new Error(input + ': ' + msg);
err.source = input;
throw err;
}
function getAST() {
var ast = matchListDefinitions();
if (input.length > 0) {
error('Invalid input not EOF');
}
return ast;
}
function matchListDefinitions() {
return matchListing(matchDefinition);
}
function matchDefinition() {
return matchGradient(
'linear-gradient',
tokens.linearGradient,
matchLinearOrientation) ||
matchGradient(
'repeating-linear-gradient',
tokens.repeatingLinearGradient,
matchLinearOrientation) ||
matchGradient(
'radial-gradient',
tokens.radialGradient,
matchListRadialOrientations) ||
matchGradient(
'repeating-radial-gradient',
tokens.repeatingRadialGradient,
matchListRadialOrientations);
}
function matchGradient(gradientType, pattern, orientationMatcher) {
return matchCall(pattern, function(captures) {
var orientation = orientationMatcher();
if (orientation) {
if (!scan(tokens.comma)) {
error('Missing comma before color stops');
}
}
return {
type: gradientType,
orientation: orientation,
colorStops: matchListing(matchColorStop)
};
});
}
function matchCall(pattern, callback) {
var captures = scan(pattern);
if (captures) {
if (!scan(tokens.startCall)) {
error('Missing (');
}
result = callback(captures);
if (!scan(tokens.endCall)) {
error('Missing )');
}
return result;
}
}
function matchLinearOrientation() {
return matchSideOrCorner() ||
matchAngle();
}
function matchSideOrCorner() {
return match('directional', tokens.sideOrCorner, 1);
}
function matchAngle() {
return match('angular', tokens.angleValue, 1);
}
function matchListRadialOrientations() {
var radialOrientations,
radialOrientation = matchRadialOrientation(),
lookaheadCache;
if (radialOrientation) {
radialOrientations = [];
radialOrientations.push(radialOrientation);
lookaheadCache = input;
if (scan(tokens.comma)) {
radialOrientation = matchRadialOrientation();
if (radialOrientation) {
radialOrientations.push(radialOrientation);
} else {
input = lookaheadCache;
}
}
}
return radialOrientations;
}
function matchRadialOrientation() {
var radialType = matchCircle() ||
matchEllipse();
if (radialType) {
radialType.at = matchAtPosition();
} else {
var defaultPosition = matchPositioning();
if (defaultPosition) {
radialType = {
type: 'default-radial',
at: defaultPosition
};
}
}
return radialType;
}
function matchCircle() {
var circle = match('shape', /^(circle)/i, 0);
if (circle) {
circle.style = matchLength() || matchExtentKeyword();
}
return circle;
}
function matchEllipse() {
var ellipse = match('shape', /^(ellipse)/i, 0);
if (ellipse) {
ellipse.style = matchDistance() || matchExtentKeyword();
}
return ellipse;
}
function matchExtentKeyword() {
return match('extent-keyword', tokens.extentKeywords, 1);
}
function matchAtPosition() {
if (match('position', /^at/, 0)) {
var positioning = matchPositioning();
if (!positioning) {
error('Missing positioning value');
}
return positioning;
}
}
function matchPositioning() {
var location = matchCoordinates();
if (location.x || location.y) {
return {
type: 'position',
value: location
};
}
}
function matchCoordinates() {
return {
x: matchDistance(),
y: matchDistance()
};
}
function matchListing(matcher) {
var captures = matcher(),
result = [];
if (captures) {
result.push(captures);
while (scan(tokens.comma)) {
captures = matcher();
if (captures) {
result.push(captures);
} else {
error('One extra comma');
}
}
}
return result;
}
function matchColorStop() {
var color = matchColor();
if (!color) {
error('Expected color definition');
}
color.length = matchDistance();
return color;
}
function matchColor() {
return matchHexColor() ||
matchRGBAColor() ||
matchRGBColor() ||
matchLiteralColor();
}
function matchLiteralColor() {
return match('literal', tokens.literalColor, 0);
}
function matchHexColor() {
return match('hex', tokens.hexColor, 1);
}
function matchRGBColor() {
return matchCall(tokens.rgbColor, function() {
return {
type: 'rgb',
value: matchListing(matchNumber)
};
});
}
function matchRGBAColor() {
return matchCall(tokens.rgbaColor, function() {
return {
type: 'rgba',
value: matchListing(matchNumber)
};
});
}
function matchNumber() {
return scan(tokens.number)[1];
}
function matchDistance() {
return match('%', tokens.percentageValue, 1) ||
matchPositionKeyword() ||
matchLength();
}
function matchPositionKeyword() {
return match('position-keyword', tokens.positionKeywords, 1);
}
function matchLength() {
return match('px', tokens.pixelValue, 1) ||
match('em', tokens.emValue, 1);
}
function match(type, pattern, captureIndex) {
var captures = scan(pattern);
if (captures) {
return {
type: type,
value: captures[captureIndex]
};
}
}
function scan(regexp) {
var captures,
blankCaptures;
blankCaptures = /^[\n\r\t\s]+/.exec(input);
if (blankCaptures) {
consume(blankCaptures[0].length);
}
captures = regexp.exec(input);
if (captures) {
consume(captures[0].length);
}
return captures;
}
function consume(size) {
input = input.substr(size);
}
return function(code) {
input = code.toString();
return getAST();
};
})();

36
node_modules/gradient-parser/gruntfile.js generated vendored Normal file
View File

@@ -0,0 +1,36 @@
'use strict';
module.exports = function (grunt) {
var config = {
app: '.',
dist: '.'
};
grunt.initConfig({
config: config,
mochaTest: {
test: {
options: {
reporter: 'spec'
},
src: ['spec/**/*.js']
}
},
concat: {
release: {
files: {
'build/node.js': ['lib/parser.js', 'index.js'],
'build/web.js': ['lib/parser.js']
}
}
}
});
grunt.loadNpmTasks('grunt-mocha-test');
grunt.loadNpmTasks('grunt-contrib-concat');
grunt.registerTask('default', [
'concat',
'mochaTest'
]);
};

12
node_modules/gradient-parser/index.html generated vendored Normal file
View File

@@ -0,0 +1,12 @@
<html>
<head>
<script src="build/web.js"></script>
<script>
document.addEventListener('DOMContentLoaded', function() {
document.body.innerHTML = '<pre>'+ JSON.stringify(GradientParser.parse('radial-gradient(ellipse cover, rgb(0, 57, 115), rgb(229, 229, 190))'), null, 2) +'</pre>';
});
</script>
</head>
<body>
</body>
</html>

1
node_modules/gradient-parser/index.js generated vendored Normal file
View File

@@ -0,0 +1 @@
exports.parse = (GradientParser || {}).parse;

337
node_modules/gradient-parser/lib/parser.js generated vendored Normal file
View File

@@ -0,0 +1,337 @@
// Copyright (c) 2014 Rafael Caricio. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
var GradientParser = {};
GradientParser.parse = (function() {
var tokens = {
linearGradient: /^(\-(webkit|o|ms|moz)\-)?(linear\-gradient)/i,
repeatingLinearGradient: /^(\-(webkit|o|ms|moz)\-)?(repeating\-linear\-gradient)/i,
radialGradient: /^(\-(webkit|o|ms|moz)\-)?(radial\-gradient)/i,
repeatingRadialGradient: /^(\-(webkit|o|ms|moz)\-)?(repeating\-radial\-gradient)/i,
sideOrCorner: /^to (left (top|bottom)|right (top|bottom)|left|right|top|bottom)/i,
extentKeywords: /^(closest\-side|closest\-corner|farthest\-side|farthest\-corner|contain|cover)/,
positionKeywords: /^(left|center|right|top|bottom)/i,
pixelValue: /^(-?(([0-9]*\.[0-9]+)|([0-9]+\.?)))px/,
percentageValue: /^(-?(([0-9]*\.[0-9]+)|([0-9]+\.?)))\%/,
emValue: /^(-?(([0-9]*\.[0-9]+)|([0-9]+\.?)))em/,
angleValue: /^(-?(([0-9]*\.[0-9]+)|([0-9]+\.?)))deg/,
startCall: /^\(/,
endCall: /^\)/,
comma: /^,/,
hexColor: /^\#([0-9a-fA-F]+)/,
literalColor: /^([a-zA-Z]+)/,
rgbColor: /^rgb/i,
rgbaColor: /^rgba/i,
number: /^(([0-9]*\.[0-9]+)|([0-9]+\.?))/
};
var input = '';
function error(msg) {
var err = new Error(input + ': ' + msg);
err.source = input;
throw err;
}
function getAST() {
var ast = matchListDefinitions();
if (input.length > 0) {
error('Invalid input not EOF');
}
return ast;
}
function matchListDefinitions() {
return matchListing(matchDefinition);
}
function matchDefinition() {
return matchGradient(
'linear-gradient',
tokens.linearGradient,
matchLinearOrientation) ||
matchGradient(
'repeating-linear-gradient',
tokens.repeatingLinearGradient,
matchLinearOrientation) ||
matchGradient(
'radial-gradient',
tokens.radialGradient,
matchListRadialOrientations) ||
matchGradient(
'repeating-radial-gradient',
tokens.repeatingRadialGradient,
matchListRadialOrientations);
}
function matchGradient(gradientType, pattern, orientationMatcher) {
return matchCall(pattern, function(captures) {
var orientation = orientationMatcher();
if (orientation) {
if (!scan(tokens.comma)) {
error('Missing comma before color stops');
}
}
return {
type: gradientType,
orientation: orientation,
colorStops: matchListing(matchColorStop)
};
});
}
function matchCall(pattern, callback) {
var captures = scan(pattern);
if (captures) {
if (!scan(tokens.startCall)) {
error('Missing (');
}
result = callback(captures);
if (!scan(tokens.endCall)) {
error('Missing )');
}
return result;
}
}
function matchLinearOrientation() {
return matchSideOrCorner() ||
matchAngle();
}
function matchSideOrCorner() {
return match('directional', tokens.sideOrCorner, 1);
}
function matchAngle() {
return match('angular', tokens.angleValue, 1);
}
function matchListRadialOrientations() {
var radialOrientations,
radialOrientation = matchRadialOrientation(),
lookaheadCache;
if (radialOrientation) {
radialOrientations = [];
radialOrientations.push(radialOrientation);
lookaheadCache = input;
if (scan(tokens.comma)) {
radialOrientation = matchRadialOrientation();
if (radialOrientation) {
radialOrientations.push(radialOrientation);
} else {
input = lookaheadCache;
}
}
}
return radialOrientations;
}
function matchRadialOrientation() {
var radialType = matchCircle() ||
matchEllipse();
if (radialType) {
radialType.at = matchAtPosition();
} else {
var defaultPosition = matchPositioning();
if (defaultPosition) {
radialType = {
type: 'default-radial',
at: defaultPosition
};
}
}
return radialType;
}
function matchCircle() {
var circle = match('shape', /^(circle)/i, 0);
if (circle) {
circle.style = matchLength() || matchExtentKeyword();
}
return circle;
}
function matchEllipse() {
var ellipse = match('shape', /^(ellipse)/i, 0);
if (ellipse) {
ellipse.style = matchDistance() || matchExtentKeyword();
}
return ellipse;
}
function matchExtentKeyword() {
return match('extent-keyword', tokens.extentKeywords, 1);
}
function matchAtPosition() {
if (match('position', /^at/, 0)) {
var positioning = matchPositioning();
if (!positioning) {
error('Missing positioning value');
}
return positioning;
}
}
function matchPositioning() {
var location = matchCoordinates();
if (location.x || location.y) {
return {
type: 'position',
value: location
};
}
}
function matchCoordinates() {
return {
x: matchDistance(),
y: matchDistance()
};
}
function matchListing(matcher) {
var captures = matcher(),
result = [];
if (captures) {
result.push(captures);
while (scan(tokens.comma)) {
captures = matcher();
if (captures) {
result.push(captures);
} else {
error('One extra comma');
}
}
}
return result;
}
function matchColorStop() {
var color = matchColor();
if (!color) {
error('Expected color definition');
}
color.length = matchDistance();
return color;
}
function matchColor() {
return matchHexColor() ||
matchRGBAColor() ||
matchRGBColor() ||
matchLiteralColor();
}
function matchLiteralColor() {
return match('literal', tokens.literalColor, 0);
}
function matchHexColor() {
return match('hex', tokens.hexColor, 1);
}
function matchRGBColor() {
return matchCall(tokens.rgbColor, function() {
return {
type: 'rgb',
value: matchListing(matchNumber)
};
});
}
function matchRGBAColor() {
return matchCall(tokens.rgbaColor, function() {
return {
type: 'rgba',
value: matchListing(matchNumber)
};
});
}
function matchNumber() {
return scan(tokens.number)[1];
}
function matchDistance() {
return match('%', tokens.percentageValue, 1) ||
matchPositionKeyword() ||
matchLength();
}
function matchPositionKeyword() {
return match('position-keyword', tokens.positionKeywords, 1);
}
function matchLength() {
return match('px', tokens.pixelValue, 1) ||
match('em', tokens.emValue, 1);
}
function match(type, pattern, captureIndex) {
var captures = scan(pattern);
if (captures) {
return {
type: type,
value: captures[captureIndex]
};
}
}
function scan(regexp) {
var captures,
blankCaptures;
blankCaptures = /^[\n\r\t\s]+/.exec(input);
if (blankCaptures) {
consume(blankCaptures[0].length);
}
captures = regexp.exec(input);
if (captures) {
consume(captures[0].length);
}
return captures;
}
function consume(size) {
input = input.substr(size);
}
return function(code) {
input = code.toString();
return getAST();
};
})();

48
node_modules/gradient-parser/package.json generated vendored Normal file
View File

@@ -0,0 +1,48 @@
{
"name": "gradient-parser",
"version": "0.1.5",
"description": "Parse CSS3 gradient definitions and return an AST.",
"author": {
"name": "Rafael Carcicio",
"email": "rafael@caricio.com",
"url": "https://github.com/rafaelcaricio"
},
"homepage": "https://github.com/rafaelcaricio/gradient-parser",
"bugs": {
"url": "https://github.com/rafaelcaricio/gradient-parser/issues"
},
"licenses": [
{
"type": "MIT",
"url": "http://rafaelcaricio.mit-license.org"
}
],
"maintainers": [],
"contributors": [],
"repository": {
"type": "git",
"url": "git://github.com/rafaelcaricio/gradient-parser.git"
},
"main": "build/node.js",
"scripts": {
"test": "grunt"
},
"keywords": [
"library",
"css3",
"parser"
],
"dependencies": {},
"devDependencies": {
"grunt": "*",
"grunt-browserify": "^3.0.1",
"grunt-complexity": "*",
"grunt-contrib-concat": "^0.5.0",
"grunt-contrib-uglify": "^0.5.1",
"grunt-mocha-test": "^0.11.0",
"mocha": "*"
},
"engines": {
"node": ">=0.10.0"
}
}

210
node_modules/gradient-parser/spec/parser.spec.js generated vendored Normal file
View File

@@ -0,0 +1,210 @@
'use strict';
var expect = require('expect.js');
var gradients = require('build/node');
describe('gradient-parser.js', function () {
var ast,
subject;
it('should exist', function () {
expect(typeof gradients.parse).to.equal('function');
});
describe('error cases', function() {
it('one more comma in definitions', function() {
expect(function() {
gradients.parse('-webkit-linear-gradient(red, blue),');
}).to.throwException(/One extra comma/);
});
it('one more comma in colors', function() {
expect(function() {
gradients.parse('-o-linear-gradient(red, blue,)');
}).to.throwException(/Expected color definition/);
});
it('invalid input', function() {
expect(function() {
gradients.parse('linear-gradient(red, blue) aaa');
}).to.throwException(/Invalid input not EOF/);
});
it('missing open call', function() {
expect(function() {
gradients.parse('linear-gradient red, blue');
}).to.throwException(/Missing \(/);
});
it('missing comma before color stops', function() {
expect(function() {
gradients.parse('linear-gradient(to right red, blue)');
}).to.throwException(/Missing comma before color stops/);
});
it('missing color stops', function() {
expect(function() {
gradients.parse('linear-gradient(to right, )');
}).to.throwException(/Expected color definition/);
});
it('missing closing call', function() {
expect(function() {
gradients.parse('linear-gradient(to right, red, blue aaa');
}).to.throwException(/Missing \)/);
});
});
describe('when parsing a simple definition', function() {
beforeEach(function() {
ast = gradients.parse('linear-gradient(red, blue)');
subject = ast[0];
});
it('should get the gradient type', function () {
expect(subject.type).to.equal('linear-gradient');
});
it('should get the orientation', function() {
expect(subject.orientation).to.be(undefined);
});
describe('colors', function() {
it('should get all colors', function() {
expect(subject.colorStops).to.have.length(2);
});
describe('first color', function() {
beforeEach(function() {
subject = subject.colorStops[0];
});
it('should get literal type', function() {
expect(subject.type).to.equal('literal');
});
it('should get the right color', function() {
expect(subject.value).to.equal('red');
});
});
describe('second color', function() {
beforeEach(function() {
subject = subject.colorStops[1];
});
it('should get literal type', function() {
expect(subject.type).to.equal('literal');
});
it('should get the right color', function() {
expect(subject.value).to.equal('blue');
});
});
});
});
describe('parse all metric values', function() {
[
'px',
'em',
'%'
].forEach(function(metric) {
describe('parse color stop for metric '+ metric, function() {
beforeEach(function() {
ast = gradients.parse('linear-gradient(blue 10' + metric + ', transparent)');
subject = ast[0];
});
describe('the first color', function() {
beforeEach(function() {
subject = subject.colorStops[0];
});
it('should have the length', function() {
expect(subject.length.type).to.equal(metric);
expect(subject.length.value).to.equal('10');
});
});
});
});
});
describe('parse all linear directional', function() {
[
{type: 'angular', unparsedValue: '145deg', value: '145'},
{type: 'directional', unparsedValue: 'to left top', value: 'left top'}
].forEach(function(orientation) {
describe('parse orientation ' + orientation.type, function() {
beforeEach(function() {
ast = gradients.parse('linear-gradient(' + orientation.unparsedValue + ', blue, green)');
subject = ast[0].orientation;
});
it('should parse value', function() {
expect(subject.type).to.equal(orientation.type);
expect(subject.value).to.equal(orientation.value);
});
});
});
});
describe('parse all color types', function() {
[
{type: 'literal', unparsedValue: 'red', value: 'red'},
{type: 'hex', unparsedValue: '#c2c2c2', value: 'c2c2c2'},
{type: 'rgb', unparsedValue: 'rgb(243, 226, 195)', value: ['243', '226', '195']},
{type: 'rgba', unparsedValue: 'rgba(243, 226, 195)', value: ['243', '226', '195']}
].forEach(function(color) {
describe('parse color type '+ color.type, function() {
beforeEach(function() {
ast = gradients.parse('linear-gradient(12deg, ' + color.unparsedValue + ', blue, green)');
subject = ast[0].colorStops[0];
});
it('should parse value', function() {
expect(subject.type).to.equal(color.type);
expect(subject.value).to.eql(color.value);
});
});
});
});
describe('parse linear gradients', function() {
[
'linear-gradient',
'radial-gradient',
'repeating-linear-gradient',
'repeating-radial-gradient'
].forEach(function(gradient) {
describe('parse ' + gradient + ' gradient', function() {
beforeEach(function() {
ast = gradients.parse(gradient + '(red, blue)');
subject = ast[0];
});
it('should parse the gradient', function() {
expect(subject.type).to.equal(gradient);
});
});
});
});
describe('different radial declarations', function() {
[
'ellipse farthest-corner',
'ellipse cover',
'circle cover',
'center bottom, ellipse cover',
'circle at 87.23px -58.3px'
].forEach(function(declaration) {
it('should parse ' + declaration + ' declaration', function() {
ast = gradients.parse('radial-gradient(' + declaration + ', red, blue)');
});
});
});
});