init
This commit is contained in:
parent
c83806f205
commit
70209ac916
|
|
@ -0,0 +1,38 @@
|
||||||
|
# -*- mode: python ; coding: utf-8 -*-
|
||||||
|
|
||||||
|
|
||||||
|
a = Analysis(
|
||||||
|
['main.py'],
|
||||||
|
pathex=[],
|
||||||
|
binaries=[],
|
||||||
|
datas=[('xhs_get_sub_comment.js', '.'), ('package.json', '.'), ('package-lock.json', '.'), ('node_modules', 'node_modules')],
|
||||||
|
hiddenimports=[],
|
||||||
|
hookspath=[],
|
||||||
|
hooksconfig={},
|
||||||
|
runtime_hooks=[],
|
||||||
|
excludes=[],
|
||||||
|
noarchive=False,
|
||||||
|
optimize=0,
|
||||||
|
)
|
||||||
|
pyz = PYZ(a.pure)
|
||||||
|
|
||||||
|
exe = EXE(
|
||||||
|
pyz,
|
||||||
|
a.scripts,
|
||||||
|
a.binaries,
|
||||||
|
a.datas,
|
||||||
|
[],
|
||||||
|
name='main',
|
||||||
|
debug=False,
|
||||||
|
bootloader_ignore_signals=False,
|
||||||
|
strip=False,
|
||||||
|
upx=True,
|
||||||
|
upx_exclude=[],
|
||||||
|
runtime_tmpdir=None,
|
||||||
|
console=False,
|
||||||
|
disable_windowed_traceback=False,
|
||||||
|
argv_emulation=False,
|
||||||
|
target_arch=None,
|
||||||
|
codesign_identity=None,
|
||||||
|
entitlements_file=None,
|
||||||
|
)
|
||||||
|
|
@ -0,0 +1,29 @@
|
||||||
|
// API
|
||||||
|
module.exports = abort;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Aborts leftover active jobs
|
||||||
|
*
|
||||||
|
* @param {object} state - current state object
|
||||||
|
*/
|
||||||
|
function abort(state)
|
||||||
|
{
|
||||||
|
Object.keys(state.jobs).forEach(clean.bind(state));
|
||||||
|
|
||||||
|
// reset leftover jobs
|
||||||
|
state.jobs = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cleans up leftover job by invoking abort function for the provided job id
|
||||||
|
*
|
||||||
|
* @this state
|
||||||
|
* @param {string|number} key - job id to abort
|
||||||
|
*/
|
||||||
|
function clean(key)
|
||||||
|
{
|
||||||
|
if (typeof this.jobs[key] == 'function')
|
||||||
|
{
|
||||||
|
this.jobs[key]();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,34 @@
|
||||||
|
var defer = require('./defer.js');
|
||||||
|
|
||||||
|
// API
|
||||||
|
module.exports = async;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Runs provided callback asynchronously
|
||||||
|
* even if callback itself is not
|
||||||
|
*
|
||||||
|
* @param {function} callback - callback to invoke
|
||||||
|
* @returns {function} - augmented callback
|
||||||
|
*/
|
||||||
|
function async(callback)
|
||||||
|
{
|
||||||
|
var isAsync = false;
|
||||||
|
|
||||||
|
// check if async happened
|
||||||
|
defer(function() { isAsync = true; });
|
||||||
|
|
||||||
|
return function async_callback(err, result)
|
||||||
|
{
|
||||||
|
if (isAsync)
|
||||||
|
{
|
||||||
|
callback(err, result);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
defer(function nextTick_callback()
|
||||||
|
{
|
||||||
|
callback(err, result);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,26 @@
|
||||||
|
module.exports = defer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Runs provided function on next iteration of the event loop
|
||||||
|
*
|
||||||
|
* @param {function} fn - function to run
|
||||||
|
*/
|
||||||
|
function defer(fn)
|
||||||
|
{
|
||||||
|
var nextTick = typeof setImmediate == 'function'
|
||||||
|
? setImmediate
|
||||||
|
: (
|
||||||
|
typeof process == 'object' && typeof process.nextTick == 'function'
|
||||||
|
? process.nextTick
|
||||||
|
: null
|
||||||
|
);
|
||||||
|
|
||||||
|
if (nextTick)
|
||||||
|
{
|
||||||
|
nextTick(fn);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
setTimeout(fn, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,75 @@
|
||||||
|
var async = require('./async.js')
|
||||||
|
, abort = require('./abort.js')
|
||||||
|
;
|
||||||
|
|
||||||
|
// API
|
||||||
|
module.exports = iterate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Iterates over each job object
|
||||||
|
*
|
||||||
|
* @param {array|object} list - array or object (named list) to iterate over
|
||||||
|
* @param {function} iterator - iterator to run
|
||||||
|
* @param {object} state - current job status
|
||||||
|
* @param {function} callback - invoked when all elements processed
|
||||||
|
*/
|
||||||
|
function iterate(list, iterator, state, callback)
|
||||||
|
{
|
||||||
|
// store current index
|
||||||
|
var key = state['keyedList'] ? state['keyedList'][state.index] : state.index;
|
||||||
|
|
||||||
|
state.jobs[key] = runJob(iterator, key, list[key], function(error, output)
|
||||||
|
{
|
||||||
|
// don't repeat yourself
|
||||||
|
// skip secondary callbacks
|
||||||
|
if (!(key in state.jobs))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// clean up jobs
|
||||||
|
delete state.jobs[key];
|
||||||
|
|
||||||
|
if (error)
|
||||||
|
{
|
||||||
|
// don't process rest of the results
|
||||||
|
// stop still active jobs
|
||||||
|
// and reset the list
|
||||||
|
abort(state);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
state.results[key] = output;
|
||||||
|
}
|
||||||
|
|
||||||
|
// return salvaged results
|
||||||
|
callback(error, state.results);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Runs iterator over provided job element
|
||||||
|
*
|
||||||
|
* @param {function} iterator - iterator to invoke
|
||||||
|
* @param {string|number} key - key/index of the element in the list of jobs
|
||||||
|
* @param {mixed} item - job description
|
||||||
|
* @param {function} callback - invoked after iterator is done with the job
|
||||||
|
* @returns {function|mixed} - job abort function or something else
|
||||||
|
*/
|
||||||
|
function runJob(iterator, key, item, callback)
|
||||||
|
{
|
||||||
|
var aborter;
|
||||||
|
|
||||||
|
// allow shortcut if iterator expects only two arguments
|
||||||
|
if (iterator.length == 2)
|
||||||
|
{
|
||||||
|
aborter = iterator(item, async(callback));
|
||||||
|
}
|
||||||
|
// otherwise go with full three arguments
|
||||||
|
else
|
||||||
|
{
|
||||||
|
aborter = iterator(item, key, async(callback));
|
||||||
|
}
|
||||||
|
|
||||||
|
return aborter;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,91 @@
|
||||||
|
var streamify = require('./streamify.js')
|
||||||
|
, defer = require('./defer.js')
|
||||||
|
;
|
||||||
|
|
||||||
|
// API
|
||||||
|
module.exports = ReadableAsyncKit;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base constructor for all streams
|
||||||
|
* used to hold properties/methods
|
||||||
|
*/
|
||||||
|
function ReadableAsyncKit()
|
||||||
|
{
|
||||||
|
ReadableAsyncKit.super_.apply(this, arguments);
|
||||||
|
|
||||||
|
// list of active jobs
|
||||||
|
this.jobs = {};
|
||||||
|
|
||||||
|
// add stream methods
|
||||||
|
this.destroy = destroy;
|
||||||
|
this._start = _start;
|
||||||
|
this._read = _read;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destroys readable stream,
|
||||||
|
* by aborting outstanding jobs
|
||||||
|
*
|
||||||
|
* @returns {void}
|
||||||
|
*/
|
||||||
|
function destroy()
|
||||||
|
{
|
||||||
|
if (this.destroyed)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.destroyed = true;
|
||||||
|
|
||||||
|
if (typeof this.terminator == 'function')
|
||||||
|
{
|
||||||
|
this.terminator();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Starts provided jobs in async manner
|
||||||
|
*
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
function _start()
|
||||||
|
{
|
||||||
|
// first argument – runner function
|
||||||
|
var runner = arguments[0]
|
||||||
|
// take away first argument
|
||||||
|
, args = Array.prototype.slice.call(arguments, 1)
|
||||||
|
// second argument - input data
|
||||||
|
, input = args[0]
|
||||||
|
// last argument - result callback
|
||||||
|
, endCb = streamify.callback.call(this, args[args.length - 1])
|
||||||
|
;
|
||||||
|
|
||||||
|
args[args.length - 1] = endCb;
|
||||||
|
// third argument - iterator
|
||||||
|
args[1] = streamify.iterator.call(this, args[1]);
|
||||||
|
|
||||||
|
// allow time for proper setup
|
||||||
|
defer(function()
|
||||||
|
{
|
||||||
|
if (!this.destroyed)
|
||||||
|
{
|
||||||
|
this.terminator = runner.apply(null, args);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
endCb(null, Array.isArray(input) ? [] : {});
|
||||||
|
}
|
||||||
|
}.bind(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implement _read to comply with Readable streams
|
||||||
|
* Doesn't really make sense for flowing object mode
|
||||||
|
*
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
function _read()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,25 @@
|
||||||
|
var parallel = require('../parallel.js');
|
||||||
|
|
||||||
|
// API
|
||||||
|
module.exports = ReadableParallel;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Streaming wrapper to `asynckit.parallel`
|
||||||
|
*
|
||||||
|
* @param {array|object} list - array or object (named list) to iterate over
|
||||||
|
* @param {function} iterator - iterator to run
|
||||||
|
* @param {function} callback - invoked when all elements processed
|
||||||
|
* @returns {stream.Readable#}
|
||||||
|
*/
|
||||||
|
function ReadableParallel(list, iterator, callback)
|
||||||
|
{
|
||||||
|
if (!(this instanceof ReadableParallel))
|
||||||
|
{
|
||||||
|
return new ReadableParallel(list, iterator, callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
// turn on object mode
|
||||||
|
ReadableParallel.super_.call(this, {objectMode: true});
|
||||||
|
|
||||||
|
this._start(parallel, list, iterator, callback);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,25 @@
|
||||||
|
var serial = require('../serial.js');
|
||||||
|
|
||||||
|
// API
|
||||||
|
module.exports = ReadableSerial;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Streaming wrapper to `asynckit.serial`
|
||||||
|
*
|
||||||
|
* @param {array|object} list - array or object (named list) to iterate over
|
||||||
|
* @param {function} iterator - iterator to run
|
||||||
|
* @param {function} callback - invoked when all elements processed
|
||||||
|
* @returns {stream.Readable#}
|
||||||
|
*/
|
||||||
|
function ReadableSerial(list, iterator, callback)
|
||||||
|
{
|
||||||
|
if (!(this instanceof ReadableSerial))
|
||||||
|
{
|
||||||
|
return new ReadableSerial(list, iterator, callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
// turn on object mode
|
||||||
|
ReadableSerial.super_.call(this, {objectMode: true});
|
||||||
|
|
||||||
|
this._start(serial, list, iterator, callback);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,29 @@
|
||||||
|
var serialOrdered = require('../serialOrdered.js');
|
||||||
|
|
||||||
|
// API
|
||||||
|
module.exports = ReadableSerialOrdered;
|
||||||
|
// expose sort helpers
|
||||||
|
module.exports.ascending = serialOrdered.ascending;
|
||||||
|
module.exports.descending = serialOrdered.descending;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Streaming wrapper to `asynckit.serialOrdered`
|
||||||
|
*
|
||||||
|
* @param {array|object} list - array or object (named list) to iterate over
|
||||||
|
* @param {function} iterator - iterator to run
|
||||||
|
* @param {function} sortMethod - custom sort function
|
||||||
|
* @param {function} callback - invoked when all elements processed
|
||||||
|
* @returns {stream.Readable#}
|
||||||
|
*/
|
||||||
|
function ReadableSerialOrdered(list, iterator, sortMethod, callback)
|
||||||
|
{
|
||||||
|
if (!(this instanceof ReadableSerialOrdered))
|
||||||
|
{
|
||||||
|
return new ReadableSerialOrdered(list, iterator, sortMethod, callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
// turn on object mode
|
||||||
|
ReadableSerialOrdered.super_.call(this, {objectMode: true});
|
||||||
|
|
||||||
|
this._start(serialOrdered, list, iterator, sortMethod, callback);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,37 @@
|
||||||
|
// API
|
||||||
|
module.exports = state;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates initial state object
|
||||||
|
* for iteration over list
|
||||||
|
*
|
||||||
|
* @param {array|object} list - list to iterate over
|
||||||
|
* @param {function|null} sortMethod - function to use for keys sort,
|
||||||
|
* or `null` to keep them as is
|
||||||
|
* @returns {object} - initial state object
|
||||||
|
*/
|
||||||
|
function state(list, sortMethod)
|
||||||
|
{
|
||||||
|
var isNamedList = !Array.isArray(list)
|
||||||
|
, initState =
|
||||||
|
{
|
||||||
|
index : 0,
|
||||||
|
keyedList: isNamedList || sortMethod ? Object.keys(list) : null,
|
||||||
|
jobs : {},
|
||||||
|
results : isNamedList ? {} : [],
|
||||||
|
size : isNamedList ? Object.keys(list).length : list.length
|
||||||
|
}
|
||||||
|
;
|
||||||
|
|
||||||
|
if (sortMethod)
|
||||||
|
{
|
||||||
|
// sort array keys based on it's values
|
||||||
|
// sort object's keys just on own merit
|
||||||
|
initState.keyedList.sort(isNamedList ? sortMethod : function(a, b)
|
||||||
|
{
|
||||||
|
return sortMethod(list[a], list[b]);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return initState;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,141 @@
|
||||||
|
var async = require('./async.js');
|
||||||
|
|
||||||
|
// API
|
||||||
|
module.exports = {
|
||||||
|
iterator: wrapIterator,
|
||||||
|
callback: wrapCallback
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wraps iterators with long signature
|
||||||
|
*
|
||||||
|
* @this ReadableAsyncKit#
|
||||||
|
* @param {function} iterator - function to wrap
|
||||||
|
* @returns {function} - wrapped function
|
||||||
|
*/
|
||||||
|
function wrapIterator(iterator)
|
||||||
|
{
|
||||||
|
var stream = this;
|
||||||
|
|
||||||
|
return function(item, key, cb)
|
||||||
|
{
|
||||||
|
var aborter
|
||||||
|
, wrappedCb = async(wrapIteratorCallback.call(stream, cb, key))
|
||||||
|
;
|
||||||
|
|
||||||
|
stream.jobs[key] = wrappedCb;
|
||||||
|
|
||||||
|
// it's either shortcut (item, cb)
|
||||||
|
if (iterator.length == 2)
|
||||||
|
{
|
||||||
|
aborter = iterator(item, wrappedCb);
|
||||||
|
}
|
||||||
|
// or long format (item, key, cb)
|
||||||
|
else
|
||||||
|
{
|
||||||
|
aborter = iterator(item, key, wrappedCb);
|
||||||
|
}
|
||||||
|
|
||||||
|
return aborter;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wraps provided callback function
|
||||||
|
* allowing to execute snitch function before
|
||||||
|
* real callback
|
||||||
|
*
|
||||||
|
* @this ReadableAsyncKit#
|
||||||
|
* @param {function} callback - function to wrap
|
||||||
|
* @returns {function} - wrapped function
|
||||||
|
*/
|
||||||
|
function wrapCallback(callback)
|
||||||
|
{
|
||||||
|
var stream = this;
|
||||||
|
|
||||||
|
var wrapped = function(error, result)
|
||||||
|
{
|
||||||
|
return finisher.call(stream, error, result, callback);
|
||||||
|
};
|
||||||
|
|
||||||
|
return wrapped;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wraps provided iterator callback function
|
||||||
|
* makes sure snitch only called once,
|
||||||
|
* but passes secondary calls to the original callback
|
||||||
|
*
|
||||||
|
* @this ReadableAsyncKit#
|
||||||
|
* @param {function} callback - callback to wrap
|
||||||
|
* @param {number|string} key - iteration key
|
||||||
|
* @returns {function} wrapped callback
|
||||||
|
*/
|
||||||
|
function wrapIteratorCallback(callback, key)
|
||||||
|
{
|
||||||
|
var stream = this;
|
||||||
|
|
||||||
|
return function(error, output)
|
||||||
|
{
|
||||||
|
// don't repeat yourself
|
||||||
|
if (!(key in stream.jobs))
|
||||||
|
{
|
||||||
|
callback(error, output);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// clean up jobs
|
||||||
|
delete stream.jobs[key];
|
||||||
|
|
||||||
|
return streamer.call(stream, error, {key: key, value: output}, callback);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stream wrapper for iterator callback
|
||||||
|
*
|
||||||
|
* @this ReadableAsyncKit#
|
||||||
|
* @param {mixed} error - error response
|
||||||
|
* @param {mixed} output - iterator output
|
||||||
|
* @param {function} callback - callback that expects iterator results
|
||||||
|
*/
|
||||||
|
function streamer(error, output, callback)
|
||||||
|
{
|
||||||
|
if (error && !this.error)
|
||||||
|
{
|
||||||
|
this.error = error;
|
||||||
|
this.pause();
|
||||||
|
this.emit('error', error);
|
||||||
|
// send back value only, as expected
|
||||||
|
callback(error, output && output.value);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// stream stuff
|
||||||
|
this.push(output);
|
||||||
|
|
||||||
|
// back to original track
|
||||||
|
// send back value only, as expected
|
||||||
|
callback(error, output && output.value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stream wrapper for finishing callback
|
||||||
|
*
|
||||||
|
* @this ReadableAsyncKit#
|
||||||
|
* @param {mixed} error - error response
|
||||||
|
* @param {mixed} output - iterator output
|
||||||
|
* @param {function} callback - callback that expects final results
|
||||||
|
*/
|
||||||
|
function finisher(error, output, callback)
|
||||||
|
{
|
||||||
|
// signal end of the stream
|
||||||
|
// only for successfully finished streams
|
||||||
|
if (!error)
|
||||||
|
{
|
||||||
|
this.push(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
// back to original track
|
||||||
|
callback(error, output);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,29 @@
|
||||||
|
var abort = require('./abort.js')
|
||||||
|
, async = require('./async.js')
|
||||||
|
;
|
||||||
|
|
||||||
|
// API
|
||||||
|
module.exports = terminator;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Terminates jobs in the attached state context
|
||||||
|
*
|
||||||
|
* @this AsyncKitState#
|
||||||
|
* @param {function} callback - final callback to invoke after termination
|
||||||
|
*/
|
||||||
|
function terminator(callback)
|
||||||
|
{
|
||||||
|
if (!Object.keys(this.jobs).length)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// fast forward iteration index
|
||||||
|
this.index = this.size;
|
||||||
|
|
||||||
|
// abort jobs
|
||||||
|
abort(this);
|
||||||
|
|
||||||
|
// send back results we have so far
|
||||||
|
async(callback)(null, this.results);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,208 @@
|
||||||
|
var util = require('util');
|
||||||
|
var Stream = require('stream').Stream;
|
||||||
|
var DelayedStream = require('delayed-stream');
|
||||||
|
|
||||||
|
module.exports = CombinedStream;
|
||||||
|
function CombinedStream() {
|
||||||
|
this.writable = false;
|
||||||
|
this.readable = true;
|
||||||
|
this.dataSize = 0;
|
||||||
|
this.maxDataSize = 2 * 1024 * 1024;
|
||||||
|
this.pauseStreams = true;
|
||||||
|
|
||||||
|
this._released = false;
|
||||||
|
this._streams = [];
|
||||||
|
this._currentStream = null;
|
||||||
|
this._insideLoop = false;
|
||||||
|
this._pendingNext = false;
|
||||||
|
}
|
||||||
|
util.inherits(CombinedStream, Stream);
|
||||||
|
|
||||||
|
CombinedStream.create = function(options) {
|
||||||
|
var combinedStream = new this();
|
||||||
|
|
||||||
|
options = options || {};
|
||||||
|
for (var option in options) {
|
||||||
|
combinedStream[option] = options[option];
|
||||||
|
}
|
||||||
|
|
||||||
|
return combinedStream;
|
||||||
|
};
|
||||||
|
|
||||||
|
CombinedStream.isStreamLike = function(stream) {
|
||||||
|
return (typeof stream !== 'function')
|
||||||
|
&& (typeof stream !== 'string')
|
||||||
|
&& (typeof stream !== 'boolean')
|
||||||
|
&& (typeof stream !== 'number')
|
||||||
|
&& (!Buffer.isBuffer(stream));
|
||||||
|
};
|
||||||
|
|
||||||
|
CombinedStream.prototype.append = function(stream) {
|
||||||
|
var isStreamLike = CombinedStream.isStreamLike(stream);
|
||||||
|
|
||||||
|
if (isStreamLike) {
|
||||||
|
if (!(stream instanceof DelayedStream)) {
|
||||||
|
var newStream = DelayedStream.create(stream, {
|
||||||
|
maxDataSize: Infinity,
|
||||||
|
pauseStream: this.pauseStreams,
|
||||||
|
});
|
||||||
|
stream.on('data', this._checkDataSize.bind(this));
|
||||||
|
stream = newStream;
|
||||||
|
}
|
||||||
|
|
||||||
|
this._handleErrors(stream);
|
||||||
|
|
||||||
|
if (this.pauseStreams) {
|
||||||
|
stream.pause();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this._streams.push(stream);
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
|
||||||
|
CombinedStream.prototype.pipe = function(dest, options) {
|
||||||
|
Stream.prototype.pipe.call(this, dest, options);
|
||||||
|
this.resume();
|
||||||
|
return dest;
|
||||||
|
};
|
||||||
|
|
||||||
|
CombinedStream.prototype._getNext = function() {
|
||||||
|
this._currentStream = null;
|
||||||
|
|
||||||
|
if (this._insideLoop) {
|
||||||
|
this._pendingNext = true;
|
||||||
|
return; // defer call
|
||||||
|
}
|
||||||
|
|
||||||
|
this._insideLoop = true;
|
||||||
|
try {
|
||||||
|
do {
|
||||||
|
this._pendingNext = false;
|
||||||
|
this._realGetNext();
|
||||||
|
} while (this._pendingNext);
|
||||||
|
} finally {
|
||||||
|
this._insideLoop = false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
CombinedStream.prototype._realGetNext = function() {
|
||||||
|
var stream = this._streams.shift();
|
||||||
|
|
||||||
|
|
||||||
|
if (typeof stream == 'undefined') {
|
||||||
|
this.end();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof stream !== 'function') {
|
||||||
|
this._pipeNext(stream);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var getStream = stream;
|
||||||
|
getStream(function(stream) {
|
||||||
|
var isStreamLike = CombinedStream.isStreamLike(stream);
|
||||||
|
if (isStreamLike) {
|
||||||
|
stream.on('data', this._checkDataSize.bind(this));
|
||||||
|
this._handleErrors(stream);
|
||||||
|
}
|
||||||
|
|
||||||
|
this._pipeNext(stream);
|
||||||
|
}.bind(this));
|
||||||
|
};
|
||||||
|
|
||||||
|
CombinedStream.prototype._pipeNext = function(stream) {
|
||||||
|
this._currentStream = stream;
|
||||||
|
|
||||||
|
var isStreamLike = CombinedStream.isStreamLike(stream);
|
||||||
|
if (isStreamLike) {
|
||||||
|
stream.on('end', this._getNext.bind(this));
|
||||||
|
stream.pipe(this, {end: false});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var value = stream;
|
||||||
|
this.write(value);
|
||||||
|
this._getNext();
|
||||||
|
};
|
||||||
|
|
||||||
|
CombinedStream.prototype._handleErrors = function(stream) {
|
||||||
|
var self = this;
|
||||||
|
stream.on('error', function(err) {
|
||||||
|
self._emitError(err);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
CombinedStream.prototype.write = function(data) {
|
||||||
|
this.emit('data', data);
|
||||||
|
};
|
||||||
|
|
||||||
|
CombinedStream.prototype.pause = function() {
|
||||||
|
if (!this.pauseStreams) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(this.pauseStreams && this._currentStream && typeof(this._currentStream.pause) == 'function') this._currentStream.pause();
|
||||||
|
this.emit('pause');
|
||||||
|
};
|
||||||
|
|
||||||
|
CombinedStream.prototype.resume = function() {
|
||||||
|
if (!this._released) {
|
||||||
|
this._released = true;
|
||||||
|
this.writable = true;
|
||||||
|
this._getNext();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(this.pauseStreams && this._currentStream && typeof(this._currentStream.resume) == 'function') this._currentStream.resume();
|
||||||
|
this.emit('resume');
|
||||||
|
};
|
||||||
|
|
||||||
|
CombinedStream.prototype.end = function() {
|
||||||
|
this._reset();
|
||||||
|
this.emit('end');
|
||||||
|
};
|
||||||
|
|
||||||
|
CombinedStream.prototype.destroy = function() {
|
||||||
|
this._reset();
|
||||||
|
this.emit('close');
|
||||||
|
};
|
||||||
|
|
||||||
|
CombinedStream.prototype._reset = function() {
|
||||||
|
this.writable = false;
|
||||||
|
this._streams = [];
|
||||||
|
this._currentStream = null;
|
||||||
|
};
|
||||||
|
|
||||||
|
CombinedStream.prototype._checkDataSize = function() {
|
||||||
|
this._updateDataSize();
|
||||||
|
if (this.dataSize <= this.maxDataSize) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var message =
|
||||||
|
'DelayedStream#maxDataSize of ' + this.maxDataSize + ' bytes exceeded.';
|
||||||
|
this._emitError(new Error(message));
|
||||||
|
};
|
||||||
|
|
||||||
|
CombinedStream.prototype._updateDataSize = function() {
|
||||||
|
this.dataSize = 0;
|
||||||
|
|
||||||
|
var self = this;
|
||||||
|
this._streams.forEach(function(stream) {
|
||||||
|
if (!stream.dataSize) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
self.dataSize += stream.dataSize;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (this._currentStream && this._currentStream.dataSize) {
|
||||||
|
this.dataSize += this._currentStream.dataSize;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
CombinedStream.prototype._emitError = function(err) {
|
||||||
|
this._reset();
|
||||||
|
this.emit('error', err);
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,271 @@
|
||||||
|
/*********************************************************************
|
||||||
|
* This is a fork from the CSS Style Declaration part of
|
||||||
|
* https://github.com/NV/CSSOM
|
||||||
|
********************************************************************/
|
||||||
|
'use strict';
|
||||||
|
var CSSOM = require('rrweb-cssom');
|
||||||
|
var allProperties = require('./allProperties');
|
||||||
|
var allExtraProperties = require('./allExtraProperties');
|
||||||
|
var implementedProperties = require('./implementedProperties');
|
||||||
|
var { dashedToCamelCase } = require('./parsers');
|
||||||
|
var getBasicPropertyDescriptor = require('./utils/getBasicPropertyDescriptor');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @constructor
|
||||||
|
* @see http://www.w3.org/TR/DOM-Level-2-Style/css.html#CSS-CSSStyleDeclaration
|
||||||
|
*/
|
||||||
|
var CSSStyleDeclaration = function CSSStyleDeclaration(onChangeCallback) {
|
||||||
|
this._values = {};
|
||||||
|
this._importants = {};
|
||||||
|
this._length = 0;
|
||||||
|
this._onChange = onChangeCallback;
|
||||||
|
this._setInProgress = false;
|
||||||
|
};
|
||||||
|
CSSStyleDeclaration.prototype = {
|
||||||
|
constructor: CSSStyleDeclaration,
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param {string} name
|
||||||
|
* @see http://www.w3.org/TR/DOM-Level-2-Style/css.html#CSS-CSSStyleDeclaration-getPropertyValue
|
||||||
|
* @return {string} the value of the property if it has been explicitly set for this declaration block.
|
||||||
|
* Returns the empty string if the property has not been set.
|
||||||
|
*/
|
||||||
|
getPropertyValue: function (name) {
|
||||||
|
if (!this._values.hasOwnProperty(name)) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
return this._values[name].toString();
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param {string} name
|
||||||
|
* @param {string} value
|
||||||
|
* @param {string} [priority=null] "important" or null
|
||||||
|
* @see http://www.w3.org/TR/DOM-Level-2-Style/css.html#CSS-CSSStyleDeclaration-setProperty
|
||||||
|
*/
|
||||||
|
setProperty: function (name, value, priority) {
|
||||||
|
if (value === undefined) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (value === null || value === '') {
|
||||||
|
this.removeProperty(name);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var isCustomProperty = name.indexOf('--') === 0;
|
||||||
|
if (isCustomProperty) {
|
||||||
|
this._setProperty(name, value, priority);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var lowercaseName = name.toLowerCase();
|
||||||
|
if (!allProperties.has(lowercaseName) && !allExtraProperties.has(lowercaseName)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this[lowercaseName] = value;
|
||||||
|
this._importants[lowercaseName] = priority;
|
||||||
|
},
|
||||||
|
_setProperty: function (name, value, priority) {
|
||||||
|
if (value === undefined) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (value === null || value === '') {
|
||||||
|
this.removeProperty(name);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var originalText;
|
||||||
|
if (this._onChange) {
|
||||||
|
originalText = this.cssText;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this._values[name]) {
|
||||||
|
// Property already exist. Overwrite it.
|
||||||
|
var index = Array.prototype.indexOf.call(this, name);
|
||||||
|
if (index < 0) {
|
||||||
|
this[this._length] = name;
|
||||||
|
this._length++;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// New property.
|
||||||
|
this[this._length] = name;
|
||||||
|
this._length++;
|
||||||
|
}
|
||||||
|
this._values[name] = value;
|
||||||
|
this._importants[name] = priority;
|
||||||
|
if (this._onChange && this.cssText !== originalText && !this._setInProgress) {
|
||||||
|
this._onChange(this.cssText);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param {string} name
|
||||||
|
* @see http://www.w3.org/TR/DOM-Level-2-Style/css.html#CSS-CSSStyleDeclaration-removeProperty
|
||||||
|
* @return {string} the value of the property if it has been explicitly set for this declaration block.
|
||||||
|
* Returns the empty string if the property has not been set or the property name does not correspond to a known CSS property.
|
||||||
|
*/
|
||||||
|
removeProperty: function (name) {
|
||||||
|
if (!this._values.hasOwnProperty(name)) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
var prevValue = this._values[name];
|
||||||
|
delete this._values[name];
|
||||||
|
delete this._importants[name];
|
||||||
|
|
||||||
|
var index = Array.prototype.indexOf.call(this, name);
|
||||||
|
if (index < 0) {
|
||||||
|
return prevValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// That's what WebKit and Opera do
|
||||||
|
Array.prototype.splice.call(this, index, 1);
|
||||||
|
|
||||||
|
// That's what Firefox does
|
||||||
|
//this[index] = ""
|
||||||
|
|
||||||
|
if (this._onChange) {
|
||||||
|
this._onChange(this.cssText);
|
||||||
|
}
|
||||||
|
return prevValue;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param {String} name
|
||||||
|
*/
|
||||||
|
getPropertyPriority: function (name) {
|
||||||
|
return this._importants[name] || '';
|
||||||
|
},
|
||||||
|
|
||||||
|
getPropertyCSSValue: function () {
|
||||||
|
//FIXME
|
||||||
|
return;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* element.style.overflow = "auto"
|
||||||
|
* element.style.getPropertyShorthand("overflow-x")
|
||||||
|
* -> "overflow"
|
||||||
|
*/
|
||||||
|
getPropertyShorthand: function () {
|
||||||
|
//FIXME
|
||||||
|
return;
|
||||||
|
},
|
||||||
|
|
||||||
|
isPropertyImplicit: function () {
|
||||||
|
//FIXME
|
||||||
|
return;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* http://www.w3.org/TR/DOM-Level-2-Style/css.html#CSS-CSSStyleDeclaration-item
|
||||||
|
*/
|
||||||
|
item: function (index) {
|
||||||
|
index = parseInt(index, 10);
|
||||||
|
if (index < 0 || index >= this._length) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
return this[index];
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
Object.defineProperties(CSSStyleDeclaration.prototype, {
|
||||||
|
cssText: {
|
||||||
|
get: function () {
|
||||||
|
var properties = [];
|
||||||
|
var i;
|
||||||
|
var name;
|
||||||
|
var value;
|
||||||
|
var priority;
|
||||||
|
for (i = 0; i < this._length; i++) {
|
||||||
|
name = this[i];
|
||||||
|
value = this.getPropertyValue(name);
|
||||||
|
priority = this.getPropertyPriority(name);
|
||||||
|
if (priority !== '') {
|
||||||
|
priority = ' !' + priority;
|
||||||
|
}
|
||||||
|
properties.push([name, ': ', value, priority, ';'].join(''));
|
||||||
|
}
|
||||||
|
return properties.join(' ');
|
||||||
|
},
|
||||||
|
set: function (value) {
|
||||||
|
var i;
|
||||||
|
this._values = {};
|
||||||
|
Array.prototype.splice.call(this, 0, this._length);
|
||||||
|
this._importants = {};
|
||||||
|
var dummyRule;
|
||||||
|
try {
|
||||||
|
dummyRule = CSSOM.parse('#bogus{' + value + '}').cssRules[0].style;
|
||||||
|
} catch (err) {
|
||||||
|
// malformed css, just return
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this._setInProgress = true;
|
||||||
|
var rule_length = dummyRule.length;
|
||||||
|
var name;
|
||||||
|
for (i = 0; i < rule_length; ++i) {
|
||||||
|
name = dummyRule[i];
|
||||||
|
this.setProperty(
|
||||||
|
dummyRule[i],
|
||||||
|
dummyRule.getPropertyValue(name),
|
||||||
|
dummyRule.getPropertyPriority(name)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
this._setInProgress = false;
|
||||||
|
if (this._onChange) {
|
||||||
|
this._onChange(this.cssText);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
enumerable: true,
|
||||||
|
configurable: true,
|
||||||
|
},
|
||||||
|
parentRule: {
|
||||||
|
get: function () {
|
||||||
|
return null;
|
||||||
|
},
|
||||||
|
enumerable: true,
|
||||||
|
configurable: true,
|
||||||
|
},
|
||||||
|
length: {
|
||||||
|
get: function () {
|
||||||
|
return this._length;
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* This deletes indices if the new length is less then the current
|
||||||
|
* length. If the new length is more, it does nothing, the new indices
|
||||||
|
* will be undefined until set.
|
||||||
|
**/
|
||||||
|
set: function (value) {
|
||||||
|
var i;
|
||||||
|
for (i = value; i < this._length; i++) {
|
||||||
|
delete this[i];
|
||||||
|
}
|
||||||
|
this._length = value;
|
||||||
|
},
|
||||||
|
enumerable: true,
|
||||||
|
configurable: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
require('./properties')(CSSStyleDeclaration.prototype);
|
||||||
|
|
||||||
|
allProperties.forEach(function (property) {
|
||||||
|
if (!implementedProperties.has(property)) {
|
||||||
|
var declaration = getBasicPropertyDescriptor(property);
|
||||||
|
Object.defineProperty(CSSStyleDeclaration.prototype, property, declaration);
|
||||||
|
Object.defineProperty(CSSStyleDeclaration.prototype, dashedToCamelCase(property), declaration);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
allExtraProperties.forEach(function (property) {
|
||||||
|
if (!implementedProperties.has(property)) {
|
||||||
|
var declaration = getBasicPropertyDescriptor(property);
|
||||||
|
Object.defineProperty(CSSStyleDeclaration.prototype, property, declaration);
|
||||||
|
Object.defineProperty(CSSStyleDeclaration.prototype, dashedToCamelCase(property), declaration);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
exports.CSSStyleDeclaration = CSSStyleDeclaration;
|
||||||
|
|
@ -0,0 +1,737 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var { CSSStyleDeclaration } = require('./CSSStyleDeclaration');
|
||||||
|
|
||||||
|
var allProperties = require('./allProperties');
|
||||||
|
var allExtraProperties = require('./allExtraProperties');
|
||||||
|
var implementedProperties = require('./implementedProperties');
|
||||||
|
var parsers = require('./parsers');
|
||||||
|
|
||||||
|
var dashedProperties = [...allProperties, ...allExtraProperties];
|
||||||
|
var allowedProperties = dashedProperties.map(parsers.dashedToCamelCase);
|
||||||
|
implementedProperties = Array.from(implementedProperties).map(parsers.dashedToCamelCase);
|
||||||
|
var invalidProperties = implementedProperties.filter((prop) => !allowedProperties.includes(prop));
|
||||||
|
|
||||||
|
describe('CSSStyleDeclaration', () => {
|
||||||
|
test('has only valid properties implemented', () => {
|
||||||
|
expect(invalidProperties.length).toEqual(0);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('has all properties', () => {
|
||||||
|
var style = new CSSStyleDeclaration();
|
||||||
|
allProperties.forEach((property) => {
|
||||||
|
expect(style.__lookupGetter__(property)).toBeTruthy();
|
||||||
|
expect(style.__lookupSetter__(property)).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test('has dashed properties', () => {
|
||||||
|
var style = new CSSStyleDeclaration();
|
||||||
|
dashedProperties.forEach((property) => {
|
||||||
|
expect(style.__lookupGetter__(property)).toBeTruthy();
|
||||||
|
expect(style.__lookupSetter__(property)).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test('has all functions', () => {
|
||||||
|
var style = new CSSStyleDeclaration();
|
||||||
|
|
||||||
|
expect(typeof style.item).toEqual('function');
|
||||||
|
expect(typeof style.getPropertyValue).toEqual('function');
|
||||||
|
expect(typeof style.setProperty).toEqual('function');
|
||||||
|
expect(typeof style.getPropertyPriority).toEqual('function');
|
||||||
|
expect(typeof style.removeProperty).toEqual('function');
|
||||||
|
|
||||||
|
// TODO - deprecated according to MDN and not implemented at all, can we remove?
|
||||||
|
expect(typeof style.getPropertyCSSValue).toEqual('function');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('has special properties', () => {
|
||||||
|
var style = new CSSStyleDeclaration();
|
||||||
|
|
||||||
|
expect(style.__lookupGetter__('cssText')).toBeTruthy();
|
||||||
|
expect(style.__lookupSetter__('cssText')).toBeTruthy();
|
||||||
|
expect(style.__lookupGetter__('length')).toBeTruthy();
|
||||||
|
expect(style.__lookupSetter__('length')).toBeTruthy();
|
||||||
|
expect(style.__lookupGetter__('parentRule')).toBeTruthy();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('from style string', () => {
|
||||||
|
var style = new CSSStyleDeclaration();
|
||||||
|
style.cssText = 'color: blue; background-color: red; width: 78%; height: 50vh;';
|
||||||
|
expect(style.length).toEqual(4);
|
||||||
|
expect(style.cssText).toEqual('color: blue; background-color: red; width: 78%; height: 50vh;');
|
||||||
|
expect(style.getPropertyValue('color')).toEqual('blue');
|
||||||
|
expect(style.item(0)).toEqual('color');
|
||||||
|
expect(style[1]).toEqual('background-color');
|
||||||
|
expect(style.backgroundColor).toEqual('red');
|
||||||
|
style.cssText = '';
|
||||||
|
expect(style.cssText).toEqual('');
|
||||||
|
expect(style.length).toEqual(0);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('from properties', () => {
|
||||||
|
var style = new CSSStyleDeclaration();
|
||||||
|
style.color = 'blue';
|
||||||
|
expect(style.length).toEqual(1);
|
||||||
|
expect(style[0]).toEqual('color');
|
||||||
|
expect(style.cssText).toEqual('color: blue;');
|
||||||
|
expect(style.item(0)).toEqual('color');
|
||||||
|
expect(style.color).toEqual('blue');
|
||||||
|
style.backgroundColor = 'red';
|
||||||
|
expect(style.length).toEqual(2);
|
||||||
|
expect(style[0]).toEqual('color');
|
||||||
|
expect(style[1]).toEqual('background-color');
|
||||||
|
expect(style.cssText).toEqual('color: blue; background-color: red;');
|
||||||
|
expect(style.backgroundColor).toEqual('red');
|
||||||
|
style.removeProperty('color');
|
||||||
|
expect(style[0]).toEqual('background-color');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('shorthand properties', () => {
|
||||||
|
var style = new CSSStyleDeclaration();
|
||||||
|
style.background = 'blue url(http://www.example.com/some_img.jpg)';
|
||||||
|
expect(style.backgroundColor).toEqual('blue');
|
||||||
|
expect(style.backgroundImage).toEqual('url(http://www.example.com/some_img.jpg)');
|
||||||
|
expect(style.background).toEqual('blue url(http://www.example.com/some_img.jpg)');
|
||||||
|
style.border = '0 solid black';
|
||||||
|
expect(style.borderWidth).toEqual('0px');
|
||||||
|
expect(style.borderStyle).toEqual('solid');
|
||||||
|
expect(style.borderColor).toEqual('black');
|
||||||
|
expect(style.borderTopWidth).toEqual('0px');
|
||||||
|
expect(style.borderLeftStyle).toEqual('solid');
|
||||||
|
expect(style.borderBottomColor).toEqual('black');
|
||||||
|
style.font = '12em monospace';
|
||||||
|
expect(style.fontSize).toEqual('12em');
|
||||||
|
expect(style.fontFamily).toEqual('monospace');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('width and height properties and null and empty strings', () => {
|
||||||
|
var style = new CSSStyleDeclaration();
|
||||||
|
style.height = 6;
|
||||||
|
expect(style.height).toEqual('');
|
||||||
|
style.width = 0;
|
||||||
|
expect(style.width).toEqual('0px');
|
||||||
|
style.height = '34%';
|
||||||
|
expect(style.height).toEqual('34%');
|
||||||
|
style.height = '100vh';
|
||||||
|
expect(style.height).toEqual('100vh');
|
||||||
|
style.height = '100vw';
|
||||||
|
expect(style.height).toEqual('100vw');
|
||||||
|
style.height = '';
|
||||||
|
expect(1).toEqual(style.length);
|
||||||
|
expect(style.cssText).toEqual('width: 0px;');
|
||||||
|
style.width = null;
|
||||||
|
expect(0).toEqual(style.length);
|
||||||
|
expect(style.cssText).toEqual('');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('implicit properties', () => {
|
||||||
|
var style = new CSSStyleDeclaration();
|
||||||
|
style.borderWidth = 0;
|
||||||
|
expect(style.length).toEqual(1);
|
||||||
|
expect(style.borderWidth).toEqual('0px');
|
||||||
|
expect(style.borderTopWidth).toEqual('0px');
|
||||||
|
expect(style.borderBottomWidth).toEqual('0px');
|
||||||
|
expect(style.borderLeftWidth).toEqual('0px');
|
||||||
|
expect(style.borderRightWidth).toEqual('0px');
|
||||||
|
expect(style.cssText).toEqual('border-width: 0px;');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('top, left, right, bottom properties', () => {
|
||||||
|
var style = new CSSStyleDeclaration();
|
||||||
|
style.top = 0;
|
||||||
|
style.left = '0%';
|
||||||
|
style.right = '5em';
|
||||||
|
style.bottom = '12pt';
|
||||||
|
expect(style.top).toEqual('0px');
|
||||||
|
expect(style.left).toEqual('0%');
|
||||||
|
expect(style.right).toEqual('5em');
|
||||||
|
expect(style.bottom).toEqual('12pt');
|
||||||
|
expect(style.length).toEqual(4);
|
||||||
|
expect(style.cssText).toEqual('top: 0px; left: 0%; right: 5em; bottom: 12pt;');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('clear and clip properties', () => {
|
||||||
|
var style = new CSSStyleDeclaration();
|
||||||
|
style.clear = 'none';
|
||||||
|
expect(style.clear).toEqual('none');
|
||||||
|
style.clear = 'lfet';
|
||||||
|
expect(style.clear).toEqual('none');
|
||||||
|
style.clear = 'left';
|
||||||
|
expect(style.clear).toEqual('left');
|
||||||
|
style.clear = 'right';
|
||||||
|
expect(style.clear).toEqual('right');
|
||||||
|
style.clear = 'both';
|
||||||
|
expect(style.clear).toEqual('both');
|
||||||
|
style.clip = 'elipse(5px, 10px)';
|
||||||
|
expect(style.clip).toEqual('');
|
||||||
|
expect(style.length).toEqual(1);
|
||||||
|
style.clip = 'rect(0, 3Em, 2pt, 50%)';
|
||||||
|
expect(style.clip).toEqual('rect(0px, 3em, 2pt, 50%)');
|
||||||
|
expect(style.length).toEqual(2);
|
||||||
|
expect(style.cssText).toEqual('clear: both; clip: rect(0px, 3em, 2pt, 50%);');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('colors', () => {
|
||||||
|
var style = new CSSStyleDeclaration();
|
||||||
|
style.color = 'rgba(0,0,0,0)';
|
||||||
|
expect(style.color).toEqual('rgba(0, 0, 0, 0)');
|
||||||
|
style.color = 'rgba(5%, 10%, 20%, 0.4)';
|
||||||
|
expect(style.color).toEqual('rgba(12, 25, 51, 0.4)');
|
||||||
|
style.color = 'rgb(33%, 34%, 33%)';
|
||||||
|
expect(style.color).toEqual('rgb(84, 86, 84)');
|
||||||
|
style.color = 'rgba(300, 200, 100, 1.5)';
|
||||||
|
expect(style.color).toEqual('rgb(255, 200, 100)');
|
||||||
|
style.color = 'hsla(0, 1%, 2%, 0.5)';
|
||||||
|
expect(style.color).toEqual('rgba(5, 5, 5, 0.5)');
|
||||||
|
style.color = 'hsl(0, 1%, 2%)';
|
||||||
|
expect(style.color).toEqual('rgb(5, 5, 5)');
|
||||||
|
style.color = 'rebeccapurple';
|
||||||
|
expect(style.color).toEqual('rebeccapurple');
|
||||||
|
style.color = 'transparent';
|
||||||
|
expect(style.color).toEqual('transparent');
|
||||||
|
style.color = 'currentcolor';
|
||||||
|
expect(style.color).toEqual('currentcolor');
|
||||||
|
style.color = '#ffffffff';
|
||||||
|
expect(style.color).toEqual('rgba(255, 255, 255, 1)');
|
||||||
|
style.color = '#fffa';
|
||||||
|
expect(style.color).toEqual('rgba(255, 255, 255, 0.667)');
|
||||||
|
style.color = '#ffffff66';
|
||||||
|
expect(style.color).toEqual('rgba(255, 255, 255, 0.4)');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('short hand properties with embedded spaces', () => {
|
||||||
|
var style = new CSSStyleDeclaration();
|
||||||
|
style.background = 'rgb(0, 0, 0) url(/something/somewhere.jpg)';
|
||||||
|
expect(style.backgroundColor).toEqual('rgb(0, 0, 0)');
|
||||||
|
expect(style.backgroundImage).toEqual('url(/something/somewhere.jpg)');
|
||||||
|
expect(style.cssText).toEqual('background: rgb(0, 0, 0) url(/something/somewhere.jpg);');
|
||||||
|
style = new CSSStyleDeclaration();
|
||||||
|
style.border = ' 1px solid black ';
|
||||||
|
expect(style.border).toEqual('1px solid black');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('setting shorthand properties to an empty string should clear all dependent properties', () => {
|
||||||
|
var style = new CSSStyleDeclaration();
|
||||||
|
style.borderWidth = '1px';
|
||||||
|
expect(style.cssText).toEqual('border-width: 1px;');
|
||||||
|
style.border = '';
|
||||||
|
expect(style.cssText).toEqual('');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('setting implicit properties to an empty string should clear all dependent properties', () => {
|
||||||
|
var style = new CSSStyleDeclaration();
|
||||||
|
style.borderTopWidth = '1px';
|
||||||
|
expect(style.cssText).toEqual('border-top-width: 1px;');
|
||||||
|
style.borderWidth = '';
|
||||||
|
expect(style.cssText).toEqual('');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('setting a shorthand property, whose shorthands are implicit properties, to an empty string should clear all dependent properties', () => {
|
||||||
|
var style = new CSSStyleDeclaration();
|
||||||
|
style.borderTopWidth = '1px';
|
||||||
|
expect(style.cssText).toEqual('border-top-width: 1px;');
|
||||||
|
style.border = '';
|
||||||
|
expect(style.cssText).toEqual('');
|
||||||
|
style.borderTop = '1px solid black';
|
||||||
|
expect(style.cssText).toEqual('border-top: 1px solid black;');
|
||||||
|
style.border = '';
|
||||||
|
expect(style.cssText).toEqual('');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('setting border values to "none" should clear dependent values', () => {
|
||||||
|
var style = new CSSStyleDeclaration();
|
||||||
|
style.borderTopWidth = '1px';
|
||||||
|
expect(style.cssText).toEqual('border-top-width: 1px;');
|
||||||
|
style.border = 'none';
|
||||||
|
expect(style.cssText).toEqual('');
|
||||||
|
style.borderTopWidth = '1px';
|
||||||
|
expect(style.cssText).toEqual('border-top-width: 1px;');
|
||||||
|
style.borderTopStyle = 'none';
|
||||||
|
expect(style.cssText).toEqual('');
|
||||||
|
style.borderTopWidth = '1px';
|
||||||
|
expect(style.cssText).toEqual('border-top-width: 1px;');
|
||||||
|
style.borderTop = 'none';
|
||||||
|
expect(style.cssText).toEqual('');
|
||||||
|
style.borderTopWidth = '1px';
|
||||||
|
style.borderLeftWidth = '1px';
|
||||||
|
expect(style.cssText).toEqual('border-top-width: 1px; border-left-width: 1px;');
|
||||||
|
style.borderTop = 'none';
|
||||||
|
expect(style.cssText).toEqual('border-left-width: 1px;');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('setting border to 0 should be okay', () => {
|
||||||
|
var style = new CSSStyleDeclaration();
|
||||||
|
style.border = 0;
|
||||||
|
expect(style.cssText).toEqual('border: 0px;');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('setting values implicit and shorthand properties via csstext and setproperty should propagate to dependent properties', () => {
|
||||||
|
var style = new CSSStyleDeclaration();
|
||||||
|
style.cssText = 'border: 1px solid black;';
|
||||||
|
expect(style.cssText).toEqual('border: 1px solid black;');
|
||||||
|
expect(style.borderTop).toEqual('1px solid black');
|
||||||
|
style.border = '';
|
||||||
|
expect(style.cssText).toEqual('');
|
||||||
|
style.setProperty('border', '1px solid black');
|
||||||
|
expect(style.cssText).toEqual('border: 1px solid black;');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('setting opacity should work', () => {
|
||||||
|
var style = new CSSStyleDeclaration();
|
||||||
|
style.setProperty('opacity', 0.75);
|
||||||
|
expect(style.cssText).toEqual('opacity: 0.75;');
|
||||||
|
style.opacity = '0.50';
|
||||||
|
expect(style.cssText).toEqual('opacity: 0.5;');
|
||||||
|
style.opacity = 1;
|
||||||
|
expect(style.cssText).toEqual('opacity: 1;');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('width and height of auto should work', () => {
|
||||||
|
var style = new CSSStyleDeclaration();
|
||||||
|
style.width = 'auto';
|
||||||
|
expect(style.cssText).toEqual('width: auto;');
|
||||||
|
expect(style.width).toEqual('auto');
|
||||||
|
style = new CSSStyleDeclaration();
|
||||||
|
style.height = 'auto';
|
||||||
|
expect(style.cssText).toEqual('height: auto;');
|
||||||
|
expect(style.height).toEqual('auto');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('padding and margin should set/clear shorthand properties', () => {
|
||||||
|
var style = new CSSStyleDeclaration();
|
||||||
|
var parts = ['Top', 'Right', 'Bottom', 'Left'];
|
||||||
|
var testParts = function (name, v, V) {
|
||||||
|
style[name] = v;
|
||||||
|
for (var i = 0; i < 4; i++) {
|
||||||
|
var part = name + parts[i];
|
||||||
|
expect(style[part]).toEqual(V[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
expect(style[name]).toEqual(v);
|
||||||
|
style[name] = '';
|
||||||
|
};
|
||||||
|
testParts('padding', '1px', ['1px', '1px', '1px', '1px']);
|
||||||
|
testParts('padding', '1px 2%', ['1px', '2%', '1px', '2%']);
|
||||||
|
testParts('padding', '1px 2px 3px', ['1px', '2px', '3px', '2px']);
|
||||||
|
testParts('padding', '1px 2px 3px 4px', ['1px', '2px', '3px', '4px']);
|
||||||
|
style.paddingTop = style.paddingRight = style.paddingBottom = style.paddingLeft = '1px';
|
||||||
|
testParts('padding', '', ['', '', '', '']);
|
||||||
|
testParts('margin', '1px', ['1px', '1px', '1px', '1px']);
|
||||||
|
testParts('margin', '1px auto', ['1px', 'auto', '1px', 'auto']);
|
||||||
|
testParts('margin', '1px 2% 3px', ['1px', '2%', '3px', '2%']);
|
||||||
|
testParts('margin', '1px 2px 3px 4px', ['1px', '2px', '3px', '4px']);
|
||||||
|
style.marginTop = style.marginRight = style.marginBottom = style.marginLeft = '1px';
|
||||||
|
testParts('margin', '', ['', '', '', '']);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('padding and margin shorthands should set main properties', () => {
|
||||||
|
var style = new CSSStyleDeclaration();
|
||||||
|
var parts = ['Top', 'Right', 'Bottom', 'Left'];
|
||||||
|
var testParts = function (name, v, V) {
|
||||||
|
var expected;
|
||||||
|
for (var i = 0; i < 4; i++) {
|
||||||
|
style[name] = v;
|
||||||
|
style[name + parts[i]] = V;
|
||||||
|
expected = v.split(/ /);
|
||||||
|
expected[i] = V;
|
||||||
|
expected = expected.join(' ');
|
||||||
|
|
||||||
|
expect(style[name]).toEqual(expected);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
testParts('padding', '1px 2px 3px 4px', '10px');
|
||||||
|
testParts('margin', '1px 2px 3px 4px', '10px');
|
||||||
|
testParts('margin', '1px 2px 3px 4px', 'auto');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('setting individual padding and margin properties to an empty string should clear them', () => {
|
||||||
|
var style = new CSSStyleDeclaration();
|
||||||
|
|
||||||
|
var properties = ['padding', 'margin'];
|
||||||
|
var parts = ['Top', 'Right', 'Bottom', 'Left'];
|
||||||
|
for (var i = 0; i < properties.length; i++) {
|
||||||
|
for (var j = 0; j < parts.length; j++) {
|
||||||
|
var property = properties[i] + parts[j];
|
||||||
|
style[property] = '12px';
|
||||||
|
expect(style[property]).toEqual('12px');
|
||||||
|
|
||||||
|
style[property] = '';
|
||||||
|
expect(style[property]).toEqual('');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
test('removing and setting individual margin properties updates the combined property accordingly', () => {
|
||||||
|
var style = new CSSStyleDeclaration();
|
||||||
|
style.margin = '1px 2px 3px 4px';
|
||||||
|
|
||||||
|
style.marginTop = '';
|
||||||
|
expect(style.margin).toEqual('');
|
||||||
|
expect(style.marginRight).toEqual('2px');
|
||||||
|
expect(style.marginBottom).toEqual('3px');
|
||||||
|
expect(style.marginLeft).toEqual('4px');
|
||||||
|
|
||||||
|
style.marginBottom = '';
|
||||||
|
expect(style.margin).toEqual('');
|
||||||
|
expect(style.marginRight).toEqual('2px');
|
||||||
|
expect(style.marginLeft).toEqual('4px');
|
||||||
|
|
||||||
|
style.marginBottom = '5px';
|
||||||
|
expect(style.margin).toEqual('');
|
||||||
|
expect(style.marginRight).toEqual('2px');
|
||||||
|
expect(style.marginBottom).toEqual('5px');
|
||||||
|
expect(style.marginLeft).toEqual('4px');
|
||||||
|
|
||||||
|
style.marginTop = '6px';
|
||||||
|
expect(style.cssText).toEqual('margin: 6px 2px 5px 4px;');
|
||||||
|
});
|
||||||
|
|
||||||
|
test.each(['padding', 'margin'])(
|
||||||
|
'removing an individual %s property should remove the combined property and replace it with the remaining individual ones',
|
||||||
|
(property) => {
|
||||||
|
var style = new CSSStyleDeclaration();
|
||||||
|
var parts = ['Top', 'Right', 'Bottom', 'Left'];
|
||||||
|
var partValues = ['1px', '2px', '3px', '4px'];
|
||||||
|
|
||||||
|
for (var j = 0; j < parts.length; j++) {
|
||||||
|
var partToRemove = parts[j];
|
||||||
|
style[property] = partValues.join(' ');
|
||||||
|
style[property + partToRemove] = '';
|
||||||
|
|
||||||
|
// Main property should have been removed
|
||||||
|
expect(style[property]).toEqual('');
|
||||||
|
|
||||||
|
// Expect other parts to still be there
|
||||||
|
for (var k = 0; k < parts.length; k++) {
|
||||||
|
var propertyCss = property + '-' + parts[k].toLowerCase() + ': ' + partValues[k] + ';';
|
||||||
|
if (k === j) {
|
||||||
|
expect(style[property + parts[k]]).toEqual('');
|
||||||
|
expect(style.cssText).not.toContain(propertyCss);
|
||||||
|
} else {
|
||||||
|
expect(style[property + parts[k]]).toEqual(partValues[k]);
|
||||||
|
expect(style.cssText).toContain(propertyCss);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
test.each(['margin', 'padding'])(
|
||||||
|
'setting additional %s properties keeps important status of others',
|
||||||
|
(property) => {
|
||||||
|
var style = new CSSStyleDeclaration();
|
||||||
|
var importantProperty = property + '-top: 3px !important;';
|
||||||
|
style.cssText = importantProperty;
|
||||||
|
expect(style.cssText).toContain(importantProperty);
|
||||||
|
|
||||||
|
style[property + 'Right'] = '4px';
|
||||||
|
style[property + 'Bottom'] = '5px';
|
||||||
|
style[property + 'Left'] = '6px';
|
||||||
|
|
||||||
|
expect(style.cssText).toContain(importantProperty);
|
||||||
|
expect(style.cssText).toContain(property + '-right: 4px;');
|
||||||
|
expect(style.cssText).toContain(property + '-bottom: 5px;');
|
||||||
|
expect(style.cssText).toContain(property + '-left: 6px;');
|
||||||
|
expect(style.cssText).not.toContain('margin:');
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
test.each(['margin', 'padding'])(
|
||||||
|
'setting individual %s keeps important status of others',
|
||||||
|
(property) => {
|
||||||
|
var style = new CSSStyleDeclaration();
|
||||||
|
style.cssText = property + ': 3px !important;';
|
||||||
|
|
||||||
|
style[property + 'Top'] = '4px';
|
||||||
|
|
||||||
|
expect(style.cssText).toContain(property + '-top: 4px;');
|
||||||
|
expect(style.cssText).toContain(property + '-right: 3px !important;');
|
||||||
|
expect(style.cssText).toContain(property + '-bottom: 3px !important;');
|
||||||
|
expect(style.cssText).toContain(property + '-left: 3px !important;');
|
||||||
|
expect(style.cssText).not.toContain('margin:');
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
test('setting a value to 0 should return the string value', () => {
|
||||||
|
var style = new CSSStyleDeclaration();
|
||||||
|
style.setProperty('fill-opacity', 0);
|
||||||
|
expect(style.fillOpacity).toEqual('0');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('onchange callback should be called when the csstext changes', () => {
|
||||||
|
var called = 0;
|
||||||
|
var style = new CSSStyleDeclaration(function (cssText) {
|
||||||
|
called++;
|
||||||
|
expect(cssText).toEqual('opacity: 0;');
|
||||||
|
});
|
||||||
|
style.cssText = 'opacity: 0;';
|
||||||
|
expect(called).toEqual(1);
|
||||||
|
style.cssText = 'opacity: 0;';
|
||||||
|
expect(called).toEqual(2);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('onchange callback should be called only once when multiple properties were added', () => {
|
||||||
|
var called = 0;
|
||||||
|
var style = new CSSStyleDeclaration(function (cssText) {
|
||||||
|
called++;
|
||||||
|
expect(cssText).toEqual('width: 100px; height: 100px;');
|
||||||
|
});
|
||||||
|
style.cssText = 'width: 100px;height:100px;';
|
||||||
|
expect(called).toEqual(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('onchange callback should not be called when property is set to the same value', () => {
|
||||||
|
var called = 0;
|
||||||
|
var style = new CSSStyleDeclaration(function () {
|
||||||
|
called++;
|
||||||
|
});
|
||||||
|
|
||||||
|
style.setProperty('opacity', 0);
|
||||||
|
expect(called).toEqual(1);
|
||||||
|
style.setProperty('opacity', 0);
|
||||||
|
expect(called).toEqual(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('onchange callback should not be called when removeProperty was called on non-existing property', () => {
|
||||||
|
var called = 0;
|
||||||
|
var style = new CSSStyleDeclaration(function () {
|
||||||
|
called++;
|
||||||
|
});
|
||||||
|
style.removeProperty('opacity');
|
||||||
|
expect(called).toEqual(0);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('setting float should work the same as cssfloat', () => {
|
||||||
|
var style = new CSSStyleDeclaration();
|
||||||
|
style.float = 'left';
|
||||||
|
expect(style.cssFloat).toEqual('left');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('setting improper css to csstext should not throw', () => {
|
||||||
|
var style = new CSSStyleDeclaration();
|
||||||
|
style.cssText = 'color: ';
|
||||||
|
expect(style.cssText).toEqual('');
|
||||||
|
style.color = 'black';
|
||||||
|
style.cssText = 'float: ';
|
||||||
|
expect(style.cssText).toEqual('');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('url parsing works with quotes', () => {
|
||||||
|
var style = new CSSStyleDeclaration();
|
||||||
|
style.backgroundImage = 'url(http://some/url/here1.png)';
|
||||||
|
expect(style.backgroundImage).toEqual('url(http://some/url/here1.png)');
|
||||||
|
style.backgroundImage = "url('http://some/url/here2.png')";
|
||||||
|
expect(style.backgroundImage).toEqual('url(http://some/url/here2.png)');
|
||||||
|
style.backgroundImage = 'url("http://some/url/here3.png")';
|
||||||
|
expect(style.backgroundImage).toEqual('url(http://some/url/here3.png)');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('setting 0 to a padding or margin works', () => {
|
||||||
|
var style = new CSSStyleDeclaration();
|
||||||
|
style.padding = 0;
|
||||||
|
expect(style.cssText).toEqual('padding: 0px;');
|
||||||
|
style.margin = '1em';
|
||||||
|
style.marginTop = '0';
|
||||||
|
expect(style.marginTop).toEqual('0px');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('setting ex units to a padding or margin works', () => {
|
||||||
|
var style = new CSSStyleDeclaration();
|
||||||
|
style.padding = '1ex';
|
||||||
|
expect(style.cssText).toEqual('padding: 1ex;');
|
||||||
|
style.margin = '1em';
|
||||||
|
style.marginTop = '0.5ex';
|
||||||
|
expect(style.marginTop).toEqual('0.5ex');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('setting empty string and null to a padding or margin works', () => {
|
||||||
|
var style = new CSSStyleDeclaration();
|
||||||
|
var parts = ['Top', 'Right', 'Bottom', 'Left'];
|
||||||
|
function testParts(base, nullValue) {
|
||||||
|
var props = [base].concat(parts.map((part) => base + part));
|
||||||
|
for (let prop of props) {
|
||||||
|
expect(style[prop]).toEqual('');
|
||||||
|
style[prop] = '10px';
|
||||||
|
expect(style[prop]).toEqual('10px');
|
||||||
|
style[prop] = nullValue;
|
||||||
|
expect(style[prop]).toEqual('');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
testParts('margin', '');
|
||||||
|
testParts('margin', null);
|
||||||
|
testParts('padding', '');
|
||||||
|
testParts('padding', null);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('setting undefined to a padding or margin does nothing', () => {
|
||||||
|
var style = new CSSStyleDeclaration();
|
||||||
|
var parts = ['Top', 'Right', 'Bottom', 'Left'];
|
||||||
|
function testParts(base) {
|
||||||
|
var props = [base].concat(parts.map((part) => base + part));
|
||||||
|
for (let prop of props) {
|
||||||
|
style[prop] = '10px';
|
||||||
|
expect(style[prop]).toEqual('10px');
|
||||||
|
style[prop] = undefined;
|
||||||
|
expect(style[prop]).toEqual('10px');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
testParts('margin');
|
||||||
|
testParts('padding');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('setting null to background works', () => {
|
||||||
|
var style = new CSSStyleDeclaration();
|
||||||
|
style.background = 'red';
|
||||||
|
expect(style.cssText).toEqual('background: red;');
|
||||||
|
style.background = null;
|
||||||
|
expect(style.cssText).toEqual('');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('flex properties should keep their values', () => {
|
||||||
|
var style = new CSSStyleDeclaration();
|
||||||
|
style.flexDirection = 'column';
|
||||||
|
expect(style.cssText).toEqual('flex-direction: column;');
|
||||||
|
style.flexDirection = 'row';
|
||||||
|
expect(style.cssText).toEqual('flex-direction: row;');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('camelcase properties are not assigned with `.setproperty()`', () => {
|
||||||
|
var style = new CSSStyleDeclaration();
|
||||||
|
style.setProperty('fontSize', '12px');
|
||||||
|
expect(style.cssText).toEqual('');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('casing is ignored in `.setproperty()`', () => {
|
||||||
|
var style = new CSSStyleDeclaration();
|
||||||
|
style.setProperty('FoNt-SiZe', '12px');
|
||||||
|
expect(style.fontSize).toEqual('12px');
|
||||||
|
expect(style.getPropertyValue('font-size')).toEqual('12px');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('support non string entries in border-spacing', () => {
|
||||||
|
var style = new CSSStyleDeclaration();
|
||||||
|
style.borderSpacing = 0;
|
||||||
|
expect(style.cssText).toEqual('border-spacing: 0px;');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('float should be valid property for `.setproperty()`', () => {
|
||||||
|
var style = new CSSStyleDeclaration();
|
||||||
|
style.setProperty('float', 'left');
|
||||||
|
expect(style.float).toEqual('left');
|
||||||
|
expect(style.getPropertyValue('float')).toEqual('left');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('flex-shrink works', () => {
|
||||||
|
var style = new CSSStyleDeclaration();
|
||||||
|
style.setProperty('flex-shrink', 0);
|
||||||
|
expect(style.getPropertyValue('flex-shrink')).toEqual('0');
|
||||||
|
style.setProperty('flex-shrink', 1);
|
||||||
|
expect(style.getPropertyValue('flex-shrink')).toEqual('1');
|
||||||
|
expect(style.cssText).toEqual('flex-shrink: 1;');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('flex-grow works', () => {
|
||||||
|
var style = new CSSStyleDeclaration();
|
||||||
|
style.setProperty('flex-grow', 2);
|
||||||
|
expect(style.getPropertyValue('flex-grow')).toEqual('2');
|
||||||
|
expect(style.cssText).toEqual('flex-grow: 2;');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('flex-basis works', () => {
|
||||||
|
var style = new CSSStyleDeclaration();
|
||||||
|
style.setProperty('flex-basis', 0);
|
||||||
|
expect(style.getPropertyValue('flex-basis')).toEqual('0px');
|
||||||
|
style.setProperty('flex-basis', '250px');
|
||||||
|
expect(style.getPropertyValue('flex-basis')).toEqual('250px');
|
||||||
|
style.setProperty('flex-basis', '10em');
|
||||||
|
expect(style.getPropertyValue('flex-basis')).toEqual('10em');
|
||||||
|
style.setProperty('flex-basis', '30%');
|
||||||
|
expect(style.getPropertyValue('flex-basis')).toEqual('30%');
|
||||||
|
expect(style.cssText).toEqual('flex-basis: 30%;');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('shorthand flex works', () => {
|
||||||
|
var style = new CSSStyleDeclaration();
|
||||||
|
style.setProperty('flex', 'none');
|
||||||
|
expect(style.getPropertyValue('flex-grow')).toEqual('0');
|
||||||
|
expect(style.getPropertyValue('flex-shrink')).toEqual('0');
|
||||||
|
expect(style.getPropertyValue('flex-basis')).toEqual('auto');
|
||||||
|
style.removeProperty('flex');
|
||||||
|
style.removeProperty('flex-basis');
|
||||||
|
style.setProperty('flex', 'auto');
|
||||||
|
expect(style.getPropertyValue('flex-grow')).toEqual('');
|
||||||
|
expect(style.getPropertyValue('flex-shrink')).toEqual('');
|
||||||
|
expect(style.getPropertyValue('flex-basis')).toEqual('auto');
|
||||||
|
style.removeProperty('flex');
|
||||||
|
style.setProperty('flex', '0 1 250px');
|
||||||
|
expect(style.getPropertyValue('flex')).toEqual('0 1 250px');
|
||||||
|
expect(style.getPropertyValue('flex-grow')).toEqual('0');
|
||||||
|
expect(style.getPropertyValue('flex-shrink')).toEqual('1');
|
||||||
|
expect(style.getPropertyValue('flex-basis')).toEqual('250px');
|
||||||
|
style.removeProperty('flex');
|
||||||
|
style.setProperty('flex', '2');
|
||||||
|
expect(style.getPropertyValue('flex-grow')).toEqual('2');
|
||||||
|
expect(style.getPropertyValue('flex-shrink')).toEqual('');
|
||||||
|
expect(style.getPropertyValue('flex-basis')).toEqual('');
|
||||||
|
style.removeProperty('flex');
|
||||||
|
style.setProperty('flex', '20%');
|
||||||
|
expect(style.getPropertyValue('flex-grow')).toEqual('');
|
||||||
|
expect(style.getPropertyValue('flex-shrink')).toEqual('');
|
||||||
|
expect(style.getPropertyValue('flex-basis')).toEqual('20%');
|
||||||
|
style.removeProperty('flex');
|
||||||
|
style.setProperty('flex', '2 2');
|
||||||
|
expect(style.getPropertyValue('flex-grow')).toEqual('2');
|
||||||
|
expect(style.getPropertyValue('flex-shrink')).toEqual('2');
|
||||||
|
expect(style.getPropertyValue('flex-basis')).toEqual('');
|
||||||
|
style.removeProperty('flex');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('font-size get a valid value', () => {
|
||||||
|
var style = new CSSStyleDeclaration();
|
||||||
|
const invalidValue = '1r5px';
|
||||||
|
style.cssText = 'font-size: 15px';
|
||||||
|
expect(1).toEqual(style.length);
|
||||||
|
style.cssText = `font-size: ${invalidValue}`;
|
||||||
|
expect(0).toEqual(style.length);
|
||||||
|
expect(undefined).toEqual(style[0]);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('getPropertyValue for custom properties in cssText', () => {
|
||||||
|
const style = new CSSStyleDeclaration();
|
||||||
|
style.cssText = '--foo: red';
|
||||||
|
|
||||||
|
expect(style.getPropertyValue('--foo')).toEqual('red');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('getPropertyValue for custom properties with setProperty', () => {
|
||||||
|
const style = new CSSStyleDeclaration();
|
||||||
|
style.setProperty('--bar', 'blue');
|
||||||
|
|
||||||
|
expect(style.getPropertyValue('--bar')).toEqual('blue');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('getPropertyValue for custom properties with object setter', () => {
|
||||||
|
const style = new CSSStyleDeclaration();
|
||||||
|
style['--baz'] = 'yellow';
|
||||||
|
|
||||||
|
expect(style.getPropertyValue('--baz')).toEqual('');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('custom properties are case-sensitive', () => {
|
||||||
|
const style = new CSSStyleDeclaration();
|
||||||
|
style.cssText = '--fOo: purple';
|
||||||
|
|
||||||
|
expect(style.getPropertyValue('--foo')).toEqual('');
|
||||||
|
expect(style.getPropertyValue('--fOo')).toEqual('purple');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('supports calc', () => {
|
||||||
|
const style = new CSSStyleDeclaration();
|
||||||
|
style.setProperty('width', 'calc(100% - 100px)');
|
||||||
|
expect(style.getPropertyValue('width')).toEqual('calc(100% - 100px)');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
@ -0,0 +1,67 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This file contains all implemented properties that are not a part of any
|
||||||
|
* current specifications or drafts, but are handled by browsers nevertheless.
|
||||||
|
*/
|
||||||
|
|
||||||
|
var allWebkitProperties = require('./allWebkitProperties');
|
||||||
|
|
||||||
|
module.exports = new Set(
|
||||||
|
[
|
||||||
|
'background-position-x',
|
||||||
|
'background-position-y',
|
||||||
|
'background-repeat-x',
|
||||||
|
'background-repeat-y',
|
||||||
|
'color-interpolation',
|
||||||
|
'color-profile',
|
||||||
|
'color-rendering',
|
||||||
|
'css-float',
|
||||||
|
'enable-background',
|
||||||
|
'fill',
|
||||||
|
'fill-opacity',
|
||||||
|
'fill-rule',
|
||||||
|
'glyph-orientation-horizontal',
|
||||||
|
'image-rendering',
|
||||||
|
'kerning',
|
||||||
|
'marker',
|
||||||
|
'marker-end',
|
||||||
|
'marker-mid',
|
||||||
|
'marker-offset',
|
||||||
|
'marker-start',
|
||||||
|
'marks',
|
||||||
|
'pointer-events',
|
||||||
|
'shape-rendering',
|
||||||
|
'size',
|
||||||
|
'src',
|
||||||
|
'stop-color',
|
||||||
|
'stop-opacity',
|
||||||
|
'stroke',
|
||||||
|
'stroke-dasharray',
|
||||||
|
'stroke-dashoffset',
|
||||||
|
'stroke-linecap',
|
||||||
|
'stroke-linejoin',
|
||||||
|
'stroke-miterlimit',
|
||||||
|
'stroke-opacity',
|
||||||
|
'stroke-width',
|
||||||
|
'text-anchor',
|
||||||
|
'text-line-through',
|
||||||
|
'text-line-through-color',
|
||||||
|
'text-line-through-mode',
|
||||||
|
'text-line-through-style',
|
||||||
|
'text-line-through-width',
|
||||||
|
'text-overline',
|
||||||
|
'text-overline-color',
|
||||||
|
'text-overline-mode',
|
||||||
|
'text-overline-style',
|
||||||
|
'text-overline-width',
|
||||||
|
'text-rendering',
|
||||||
|
'text-underline',
|
||||||
|
'text-underline-color',
|
||||||
|
'text-underline-mode',
|
||||||
|
'text-underline-style',
|
||||||
|
'text-underline-width',
|
||||||
|
'unicode-range',
|
||||||
|
'vector-effect',
|
||||||
|
].concat(allWebkitProperties)
|
||||||
|
);
|
||||||
|
|
@ -0,0 +1,519 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
// autogenerated - 1/22/2023
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
* https://www.w3.org/Style/CSS/all-properties.en.html
|
||||||
|
*/
|
||||||
|
|
||||||
|
module.exports = new Set([
|
||||||
|
'-webkit-line-clamp',
|
||||||
|
'accent-color',
|
||||||
|
'align-content',
|
||||||
|
'align-items',
|
||||||
|
'align-self',
|
||||||
|
'alignment-baseline',
|
||||||
|
'all',
|
||||||
|
'animation',
|
||||||
|
'animation-delay',
|
||||||
|
'animation-delay-end',
|
||||||
|
'animation-delay-start',
|
||||||
|
'animation-direction',
|
||||||
|
'animation-duration',
|
||||||
|
'animation-fill-mode',
|
||||||
|
'animation-iteration-count',
|
||||||
|
'animation-name',
|
||||||
|
'animation-play-state',
|
||||||
|
'animation-range',
|
||||||
|
'animation-timing-function',
|
||||||
|
'appearance',
|
||||||
|
'aspect-ratio',
|
||||||
|
'azimuth',
|
||||||
|
'backface-visibility',
|
||||||
|
'background',
|
||||||
|
'background-attachment',
|
||||||
|
'background-blend-mode',
|
||||||
|
'background-clip',
|
||||||
|
'background-color',
|
||||||
|
'background-image',
|
||||||
|
'background-origin',
|
||||||
|
'background-position',
|
||||||
|
'background-repeat',
|
||||||
|
'background-size',
|
||||||
|
'baseline-shift',
|
||||||
|
'baseline-source',
|
||||||
|
'block-ellipsis',
|
||||||
|
'block-size',
|
||||||
|
'bookmark-label',
|
||||||
|
'bookmark-level',
|
||||||
|
'bookmark-state',
|
||||||
|
'border',
|
||||||
|
'border-block',
|
||||||
|
'border-block-color',
|
||||||
|
'border-block-end',
|
||||||
|
'border-block-end-color',
|
||||||
|
'border-block-end-style',
|
||||||
|
'border-block-end-width',
|
||||||
|
'border-block-start',
|
||||||
|
'border-block-start-color',
|
||||||
|
'border-block-start-style',
|
||||||
|
'border-block-start-width',
|
||||||
|
'border-block-style',
|
||||||
|
'border-block-width',
|
||||||
|
'border-bottom',
|
||||||
|
'border-bottom-color',
|
||||||
|
'border-bottom-left-radius',
|
||||||
|
'border-bottom-right-radius',
|
||||||
|
'border-bottom-style',
|
||||||
|
'border-bottom-width',
|
||||||
|
'border-boundary',
|
||||||
|
'border-collapse',
|
||||||
|
'border-color',
|
||||||
|
'border-end-end-radius',
|
||||||
|
'border-end-start-radius',
|
||||||
|
'border-image',
|
||||||
|
'border-image-outset',
|
||||||
|
'border-image-repeat',
|
||||||
|
'border-image-slice',
|
||||||
|
'border-image-source',
|
||||||
|
'border-image-width',
|
||||||
|
'border-inline',
|
||||||
|
'border-inline-color',
|
||||||
|
'border-inline-end',
|
||||||
|
'border-inline-end-color',
|
||||||
|
'border-inline-end-style',
|
||||||
|
'border-inline-end-width',
|
||||||
|
'border-inline-start',
|
||||||
|
'border-inline-start-color',
|
||||||
|
'border-inline-start-style',
|
||||||
|
'border-inline-start-width',
|
||||||
|
'border-inline-style',
|
||||||
|
'border-inline-width',
|
||||||
|
'border-left',
|
||||||
|
'border-left-color',
|
||||||
|
'border-left-style',
|
||||||
|
'border-left-width',
|
||||||
|
'border-radius',
|
||||||
|
'border-right',
|
||||||
|
'border-right-color',
|
||||||
|
'border-right-style',
|
||||||
|
'border-right-width',
|
||||||
|
'border-spacing',
|
||||||
|
'border-start-end-radius',
|
||||||
|
'border-start-start-radius',
|
||||||
|
'border-style',
|
||||||
|
'border-top',
|
||||||
|
'border-top-color',
|
||||||
|
'border-top-left-radius',
|
||||||
|
'border-top-right-radius',
|
||||||
|
'border-top-style',
|
||||||
|
'border-top-width',
|
||||||
|
'border-width',
|
||||||
|
'bottom',
|
||||||
|
'box-decoration-break',
|
||||||
|
'box-shadow',
|
||||||
|
'box-sizing',
|
||||||
|
'box-snap',
|
||||||
|
'break-after',
|
||||||
|
'break-before',
|
||||||
|
'break-inside',
|
||||||
|
'caption-side',
|
||||||
|
'caret',
|
||||||
|
'caret-color',
|
||||||
|
'caret-shape',
|
||||||
|
'chains',
|
||||||
|
'clear',
|
||||||
|
'clip',
|
||||||
|
'clip-path',
|
||||||
|
'clip-rule',
|
||||||
|
'color',
|
||||||
|
'color-adjust',
|
||||||
|
'color-interpolation-filters',
|
||||||
|
'color-scheme',
|
||||||
|
'column-count',
|
||||||
|
'column-fill',
|
||||||
|
'column-gap',
|
||||||
|
'column-rule',
|
||||||
|
'column-rule-color',
|
||||||
|
'column-rule-style',
|
||||||
|
'column-rule-width',
|
||||||
|
'column-span',
|
||||||
|
'column-width',
|
||||||
|
'columns',
|
||||||
|
'contain',
|
||||||
|
'contain-intrinsic-block-size',
|
||||||
|
'contain-intrinsic-height',
|
||||||
|
'contain-intrinsic-inline-size',
|
||||||
|
'contain-intrinsic-size',
|
||||||
|
'contain-intrinsic-width',
|
||||||
|
'container',
|
||||||
|
'container-name',
|
||||||
|
'container-type',
|
||||||
|
'content',
|
||||||
|
'content-visibility',
|
||||||
|
'continue',
|
||||||
|
'counter-increment',
|
||||||
|
'counter-reset',
|
||||||
|
'counter-set',
|
||||||
|
'cue',
|
||||||
|
'cue-after',
|
||||||
|
'cue-before',
|
||||||
|
'cursor',
|
||||||
|
'direction',
|
||||||
|
'display',
|
||||||
|
'dominant-baseline',
|
||||||
|
'elevation',
|
||||||
|
'empty-cells',
|
||||||
|
'filter',
|
||||||
|
'flex',
|
||||||
|
'flex-basis',
|
||||||
|
'flex-direction',
|
||||||
|
'flex-flow',
|
||||||
|
'flex-grow',
|
||||||
|
'flex-shrink',
|
||||||
|
'flex-wrap',
|
||||||
|
'float',
|
||||||
|
'flood-color',
|
||||||
|
'flood-opacity',
|
||||||
|
'flow',
|
||||||
|
'flow-from',
|
||||||
|
'flow-into',
|
||||||
|
'font',
|
||||||
|
'font-family',
|
||||||
|
'font-feature-settings',
|
||||||
|
'font-kerning',
|
||||||
|
'font-language-override',
|
||||||
|
'font-optical-sizing',
|
||||||
|
'font-palette',
|
||||||
|
'font-size',
|
||||||
|
'font-size-adjust',
|
||||||
|
'font-stretch',
|
||||||
|
'font-style',
|
||||||
|
'font-synthesis',
|
||||||
|
'font-synthesis-small-caps',
|
||||||
|
'font-synthesis-style',
|
||||||
|
'font-synthesis-weight',
|
||||||
|
'font-variant',
|
||||||
|
'font-variant-alternates',
|
||||||
|
'font-variant-caps',
|
||||||
|
'font-variant-east-asian',
|
||||||
|
'font-variant-emoji',
|
||||||
|
'font-variant-ligatures',
|
||||||
|
'font-variant-numeric',
|
||||||
|
'font-variant-position',
|
||||||
|
'font-variation-settings',
|
||||||
|
'font-weight',
|
||||||
|
'footnote-display',
|
||||||
|
'footnote-policy',
|
||||||
|
'forced-color-adjust',
|
||||||
|
'gap',
|
||||||
|
'glyph-orientation-vertical',
|
||||||
|
'grid',
|
||||||
|
'grid-area',
|
||||||
|
'grid-auto-columns',
|
||||||
|
'grid-auto-flow',
|
||||||
|
'grid-auto-rows',
|
||||||
|
'grid-column',
|
||||||
|
'grid-column-end',
|
||||||
|
'grid-column-start',
|
||||||
|
'grid-row',
|
||||||
|
'grid-row-end',
|
||||||
|
'grid-row-start',
|
||||||
|
'grid-template',
|
||||||
|
'grid-template-areas',
|
||||||
|
'grid-template-columns',
|
||||||
|
'grid-template-rows',
|
||||||
|
'hanging-punctuation',
|
||||||
|
'height',
|
||||||
|
'hyphenate-character',
|
||||||
|
'hyphenate-limit-chars',
|
||||||
|
'hyphenate-limit-last',
|
||||||
|
'hyphenate-limit-lines',
|
||||||
|
'hyphenate-limit-zone',
|
||||||
|
'hyphens',
|
||||||
|
'image-orientation',
|
||||||
|
'image-rendering',
|
||||||
|
'image-resolution',
|
||||||
|
'initial-letter',
|
||||||
|
'initial-letter-align',
|
||||||
|
'initial-letter-wrap',
|
||||||
|
'inline-size',
|
||||||
|
'inline-sizing',
|
||||||
|
'inset',
|
||||||
|
'inset-block',
|
||||||
|
'inset-block-end',
|
||||||
|
'inset-block-start',
|
||||||
|
'inset-inline',
|
||||||
|
'inset-inline-end',
|
||||||
|
'inset-inline-start',
|
||||||
|
'isolation',
|
||||||
|
'justify-content',
|
||||||
|
'justify-items',
|
||||||
|
'justify-self',
|
||||||
|
'leading-trim',
|
||||||
|
'left',
|
||||||
|
'letter-spacing',
|
||||||
|
'lighting-color',
|
||||||
|
'line-break',
|
||||||
|
'line-clamp',
|
||||||
|
'line-grid',
|
||||||
|
'line-height',
|
||||||
|
'line-padding',
|
||||||
|
'line-snap',
|
||||||
|
'list-style',
|
||||||
|
'list-style-image',
|
||||||
|
'list-style-position',
|
||||||
|
'list-style-type',
|
||||||
|
'margin',
|
||||||
|
'margin-block',
|
||||||
|
'margin-block-end',
|
||||||
|
'margin-block-start',
|
||||||
|
'margin-bottom',
|
||||||
|
'margin-inline',
|
||||||
|
'margin-inline-end',
|
||||||
|
'margin-inline-start',
|
||||||
|
'margin-left',
|
||||||
|
'margin-right',
|
||||||
|
'margin-top',
|
||||||
|
'margin-trim',
|
||||||
|
'marker-side',
|
||||||
|
'mask',
|
||||||
|
'mask-border',
|
||||||
|
'mask-border-mode',
|
||||||
|
'mask-border-outset',
|
||||||
|
'mask-border-repeat',
|
||||||
|
'mask-border-slice',
|
||||||
|
'mask-border-source',
|
||||||
|
'mask-border-width',
|
||||||
|
'mask-clip',
|
||||||
|
'mask-composite',
|
||||||
|
'mask-image',
|
||||||
|
'mask-mode',
|
||||||
|
'mask-origin',
|
||||||
|
'mask-position',
|
||||||
|
'mask-repeat',
|
||||||
|
'mask-size',
|
||||||
|
'mask-type',
|
||||||
|
'max-block-size',
|
||||||
|
'max-height',
|
||||||
|
'max-inline-size',
|
||||||
|
'max-lines',
|
||||||
|
'max-width',
|
||||||
|
'min-block-size',
|
||||||
|
'min-height',
|
||||||
|
'min-inline-size',
|
||||||
|
'min-intrinsic-sizing',
|
||||||
|
'min-width',
|
||||||
|
'mix-blend-mode',
|
||||||
|
'nav-down',
|
||||||
|
'nav-left',
|
||||||
|
'nav-right',
|
||||||
|
'nav-up',
|
||||||
|
'object-fit',
|
||||||
|
'object-position',
|
||||||
|
'offset',
|
||||||
|
'offset-anchor',
|
||||||
|
'offset-distance',
|
||||||
|
'offset-path',
|
||||||
|
'offset-position',
|
||||||
|
'offset-rotate',
|
||||||
|
'opacity',
|
||||||
|
'order',
|
||||||
|
'orphans',
|
||||||
|
'outline',
|
||||||
|
'outline-color',
|
||||||
|
'outline-offset',
|
||||||
|
'outline-style',
|
||||||
|
'outline-width',
|
||||||
|
'overflow',
|
||||||
|
'overflow-anchor',
|
||||||
|
'overflow-block',
|
||||||
|
'overflow-clip-margin',
|
||||||
|
'overflow-clip-margin-block',
|
||||||
|
'overflow-clip-margin-block-end',
|
||||||
|
'overflow-clip-margin-block-start',
|
||||||
|
'overflow-clip-margin-bottom',
|
||||||
|
'overflow-clip-margin-inline',
|
||||||
|
'overflow-clip-margin-inline-end',
|
||||||
|
'overflow-clip-margin-inline-start',
|
||||||
|
'overflow-clip-margin-left',
|
||||||
|
'overflow-clip-margin-right',
|
||||||
|
'overflow-clip-margin-top',
|
||||||
|
'overflow-inline',
|
||||||
|
'overflow-wrap',
|
||||||
|
'overflow-x',
|
||||||
|
'overflow-y',
|
||||||
|
'padding',
|
||||||
|
'padding-block',
|
||||||
|
'padding-block-end',
|
||||||
|
'padding-block-start',
|
||||||
|
'padding-bottom',
|
||||||
|
'padding-inline',
|
||||||
|
'padding-inline-end',
|
||||||
|
'padding-inline-start',
|
||||||
|
'padding-left',
|
||||||
|
'padding-right',
|
||||||
|
'padding-top',
|
||||||
|
'page',
|
||||||
|
'page-break-after',
|
||||||
|
'page-break-before',
|
||||||
|
'page-break-inside',
|
||||||
|
'pause',
|
||||||
|
'pause-after',
|
||||||
|
'pause-before',
|
||||||
|
'perspective',
|
||||||
|
'perspective-origin',
|
||||||
|
'pitch',
|
||||||
|
'pitch-range',
|
||||||
|
'place-content',
|
||||||
|
'place-items',
|
||||||
|
'place-self',
|
||||||
|
'play-during',
|
||||||
|
'position',
|
||||||
|
'print-color-adjust',
|
||||||
|
'quotes',
|
||||||
|
'region-fragment',
|
||||||
|
'resize',
|
||||||
|
'rest',
|
||||||
|
'rest-after',
|
||||||
|
'rest-before',
|
||||||
|
'richness',
|
||||||
|
'right',
|
||||||
|
'rotate',
|
||||||
|
'row-gap',
|
||||||
|
'ruby-align',
|
||||||
|
'ruby-merge',
|
||||||
|
'ruby-overhang',
|
||||||
|
'ruby-position',
|
||||||
|
'running',
|
||||||
|
'scale',
|
||||||
|
'scroll-behavior',
|
||||||
|
'scroll-margin',
|
||||||
|
'scroll-margin-block',
|
||||||
|
'scroll-margin-block-end',
|
||||||
|
'scroll-margin-block-start',
|
||||||
|
'scroll-margin-bottom',
|
||||||
|
'scroll-margin-inline',
|
||||||
|
'scroll-margin-inline-end',
|
||||||
|
'scroll-margin-inline-start',
|
||||||
|
'scroll-margin-left',
|
||||||
|
'scroll-margin-right',
|
||||||
|
'scroll-margin-top',
|
||||||
|
'scroll-padding',
|
||||||
|
'scroll-padding-block',
|
||||||
|
'scroll-padding-block-end',
|
||||||
|
'scroll-padding-block-start',
|
||||||
|
'scroll-padding-bottom',
|
||||||
|
'scroll-padding-inline',
|
||||||
|
'scroll-padding-inline-end',
|
||||||
|
'scroll-padding-inline-start',
|
||||||
|
'scroll-padding-left',
|
||||||
|
'scroll-padding-right',
|
||||||
|
'scroll-padding-top',
|
||||||
|
'scroll-snap-align',
|
||||||
|
'scroll-snap-stop',
|
||||||
|
'scroll-snap-type',
|
||||||
|
'scroll-timeline',
|
||||||
|
'scroll-timeline-axis',
|
||||||
|
'scroll-timeline-name',
|
||||||
|
'scrollbar-color',
|
||||||
|
'scrollbar-gutter',
|
||||||
|
'scrollbar-width',
|
||||||
|
'shape-image-threshold',
|
||||||
|
'shape-inside',
|
||||||
|
'shape-margin',
|
||||||
|
'shape-outside',
|
||||||
|
'spatial-navigation-action',
|
||||||
|
'spatial-navigation-contain',
|
||||||
|
'spatial-navigation-function',
|
||||||
|
'speak',
|
||||||
|
'speak-as',
|
||||||
|
'speak-header',
|
||||||
|
'speak-numeral',
|
||||||
|
'speak-punctuation',
|
||||||
|
'speech-rate',
|
||||||
|
'stress',
|
||||||
|
'string-set',
|
||||||
|
'tab-size',
|
||||||
|
'table-layout',
|
||||||
|
'text-align',
|
||||||
|
'text-align-all',
|
||||||
|
'text-align-last',
|
||||||
|
'text-combine-upright',
|
||||||
|
'text-decoration',
|
||||||
|
'text-decoration-color',
|
||||||
|
'text-decoration-line',
|
||||||
|
'text-decoration-skip',
|
||||||
|
'text-decoration-skip-box',
|
||||||
|
'text-decoration-skip-ink',
|
||||||
|
'text-decoration-skip-inset',
|
||||||
|
'text-decoration-skip-self',
|
||||||
|
'text-decoration-skip-spaces',
|
||||||
|
'text-decoration-style',
|
||||||
|
'text-decoration-thickness',
|
||||||
|
'text-edge',
|
||||||
|
'text-emphasis',
|
||||||
|
'text-emphasis-color',
|
||||||
|
'text-emphasis-position',
|
||||||
|
'text-emphasis-skip',
|
||||||
|
'text-emphasis-style',
|
||||||
|
'text-group-align',
|
||||||
|
'text-indent',
|
||||||
|
'text-justify',
|
||||||
|
'text-orientation',
|
||||||
|
'text-overflow',
|
||||||
|
'text-shadow',
|
||||||
|
'text-space-collapse',
|
||||||
|
'text-space-trim',
|
||||||
|
'text-spacing',
|
||||||
|
'text-transform',
|
||||||
|
'text-underline-offset',
|
||||||
|
'text-underline-position',
|
||||||
|
'text-wrap',
|
||||||
|
'top',
|
||||||
|
'transform',
|
||||||
|
'transform-box',
|
||||||
|
'transform-origin',
|
||||||
|
'transform-style',
|
||||||
|
'transition',
|
||||||
|
'transition-delay',
|
||||||
|
'transition-duration',
|
||||||
|
'transition-property',
|
||||||
|
'transition-timing-function',
|
||||||
|
'translate',
|
||||||
|
'unicode-bidi',
|
||||||
|
'user-select',
|
||||||
|
'vertical-align',
|
||||||
|
'view-timeline',
|
||||||
|
'view-timeline-axis',
|
||||||
|
'view-timeline-inset',
|
||||||
|
'view-timeline-name',
|
||||||
|
'view-transition-name',
|
||||||
|
'visibility',
|
||||||
|
'voice-balance',
|
||||||
|
'voice-duration',
|
||||||
|
'voice-family',
|
||||||
|
'voice-pitch',
|
||||||
|
'voice-range',
|
||||||
|
'voice-rate',
|
||||||
|
'voice-stress',
|
||||||
|
'voice-volume',
|
||||||
|
'volume',
|
||||||
|
'white-space',
|
||||||
|
'widows',
|
||||||
|
'width',
|
||||||
|
'will-change',
|
||||||
|
'word-boundary-detection',
|
||||||
|
'word-boundary-expansion',
|
||||||
|
'word-break',
|
||||||
|
'word-spacing',
|
||||||
|
'word-wrap',
|
||||||
|
'wrap-after',
|
||||||
|
'wrap-before',
|
||||||
|
'wrap-flow',
|
||||||
|
'wrap-inside',
|
||||||
|
'wrap-through',
|
||||||
|
'writing-mode',
|
||||||
|
'z-index',
|
||||||
|
]);
|
||||||
|
|
@ -0,0 +1,194 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This file contains all implemented properties that are not a part of any
|
||||||
|
* current specifications or drafts, but are handled by browsers nevertheless.
|
||||||
|
*/
|
||||||
|
|
||||||
|
module.exports = [
|
||||||
|
'animation',
|
||||||
|
'animation-delay',
|
||||||
|
'animation-direction',
|
||||||
|
'animation-duration',
|
||||||
|
'animation-fill-mode',
|
||||||
|
'animation-iteration-count',
|
||||||
|
'animation-name',
|
||||||
|
'animation-play-state',
|
||||||
|
'animation-timing-function',
|
||||||
|
'appearance',
|
||||||
|
'aspect-ratio',
|
||||||
|
'backface-visibility',
|
||||||
|
'background-clip',
|
||||||
|
'background-composite',
|
||||||
|
'background-origin',
|
||||||
|
'background-size',
|
||||||
|
'border-after',
|
||||||
|
'border-after-color',
|
||||||
|
'border-after-style',
|
||||||
|
'border-after-width',
|
||||||
|
'border-before',
|
||||||
|
'border-before-color',
|
||||||
|
'border-before-style',
|
||||||
|
'border-before-width',
|
||||||
|
'border-end',
|
||||||
|
'border-end-color',
|
||||||
|
'border-end-style',
|
||||||
|
'border-end-width',
|
||||||
|
'border-fit',
|
||||||
|
'border-horizontal-spacing',
|
||||||
|
'border-image',
|
||||||
|
'border-radius',
|
||||||
|
'border-start',
|
||||||
|
'border-start-color',
|
||||||
|
'border-start-style',
|
||||||
|
'border-start-width',
|
||||||
|
'border-vertical-spacing',
|
||||||
|
'box-align',
|
||||||
|
'box-direction',
|
||||||
|
'box-flex',
|
||||||
|
'box-flex-group',
|
||||||
|
'box-lines',
|
||||||
|
'box-ordinal-group',
|
||||||
|
'box-orient',
|
||||||
|
'box-pack',
|
||||||
|
'box-reflect',
|
||||||
|
'box-shadow',
|
||||||
|
'color-correction',
|
||||||
|
'column-axis',
|
||||||
|
'column-break-after',
|
||||||
|
'column-break-before',
|
||||||
|
'column-break-inside',
|
||||||
|
'column-count',
|
||||||
|
'column-gap',
|
||||||
|
'column-rule',
|
||||||
|
'column-rule-color',
|
||||||
|
'column-rule-style',
|
||||||
|
'column-rule-width',
|
||||||
|
'columns',
|
||||||
|
'column-span',
|
||||||
|
'column-width',
|
||||||
|
'filter',
|
||||||
|
'flex-align',
|
||||||
|
'flex-direction',
|
||||||
|
'flex-flow',
|
||||||
|
'flex-item-align',
|
||||||
|
'flex-line-pack',
|
||||||
|
'flex-order',
|
||||||
|
'flex-pack',
|
||||||
|
'flex-wrap',
|
||||||
|
'flow-from',
|
||||||
|
'flow-into',
|
||||||
|
'font-feature-settings',
|
||||||
|
'font-kerning',
|
||||||
|
'font-size-delta',
|
||||||
|
'font-smoothing',
|
||||||
|
'font-variant-ligatures',
|
||||||
|
'highlight',
|
||||||
|
'hyphenate-character',
|
||||||
|
'hyphenate-limit-after',
|
||||||
|
'hyphenate-limit-before',
|
||||||
|
'hyphenate-limit-lines',
|
||||||
|
'hyphens',
|
||||||
|
'line-align',
|
||||||
|
'line-box-contain',
|
||||||
|
'line-break',
|
||||||
|
'line-clamp',
|
||||||
|
'line-grid',
|
||||||
|
'line-snap',
|
||||||
|
'locale',
|
||||||
|
'logical-height',
|
||||||
|
'logical-width',
|
||||||
|
'margin-after',
|
||||||
|
'margin-after-collapse',
|
||||||
|
'margin-before',
|
||||||
|
'margin-before-collapse',
|
||||||
|
'margin-bottom-collapse',
|
||||||
|
'margin-collapse',
|
||||||
|
'margin-end',
|
||||||
|
'margin-start',
|
||||||
|
'margin-top-collapse',
|
||||||
|
'marquee',
|
||||||
|
'marquee-direction',
|
||||||
|
'marquee-increment',
|
||||||
|
'marquee-repetition',
|
||||||
|
'marquee-speed',
|
||||||
|
'marquee-style',
|
||||||
|
'mask',
|
||||||
|
'mask-attachment',
|
||||||
|
'mask-box-image',
|
||||||
|
'mask-box-image-outset',
|
||||||
|
'mask-box-image-repeat',
|
||||||
|
'mask-box-image-slice',
|
||||||
|
'mask-box-image-source',
|
||||||
|
'mask-box-image-width',
|
||||||
|
'mask-clip',
|
||||||
|
'mask-composite',
|
||||||
|
'mask-image',
|
||||||
|
'mask-origin',
|
||||||
|
'mask-position',
|
||||||
|
'mask-position-x',
|
||||||
|
'mask-position-y',
|
||||||
|
'mask-repeat',
|
||||||
|
'mask-repeat-x',
|
||||||
|
'mask-repeat-y',
|
||||||
|
'mask-size',
|
||||||
|
'match-nearest-mail-blockquote-color',
|
||||||
|
'max-logical-height',
|
||||||
|
'max-logical-width',
|
||||||
|
'min-logical-height',
|
||||||
|
'min-logical-width',
|
||||||
|
'nbsp-mode',
|
||||||
|
'overflow-scrolling',
|
||||||
|
'padding-after',
|
||||||
|
'padding-before',
|
||||||
|
'padding-end',
|
||||||
|
'padding-start',
|
||||||
|
'perspective',
|
||||||
|
'perspective-origin',
|
||||||
|
'perspective-origin-x',
|
||||||
|
'perspective-origin-y',
|
||||||
|
'print-color-adjust',
|
||||||
|
'region-break-after',
|
||||||
|
'region-break-before',
|
||||||
|
'region-break-inside',
|
||||||
|
'region-overflow',
|
||||||
|
'rtl-ordering',
|
||||||
|
'svg-shadow',
|
||||||
|
'tap-highlight-color',
|
||||||
|
'text-combine',
|
||||||
|
'text-decorations-in-effect',
|
||||||
|
'text-emphasis',
|
||||||
|
'text-emphasis-color',
|
||||||
|
'text-emphasis-position',
|
||||||
|
'text-emphasis-style',
|
||||||
|
'text-fill-color',
|
||||||
|
'text-orientation',
|
||||||
|
'text-security',
|
||||||
|
'text-size-adjust',
|
||||||
|
'text-stroke',
|
||||||
|
'text-stroke-color',
|
||||||
|
'text-stroke-width',
|
||||||
|
'transform',
|
||||||
|
'transform-origin',
|
||||||
|
'transform-origin-x',
|
||||||
|
'transform-origin-y',
|
||||||
|
'transform-origin-z',
|
||||||
|
'transform-style',
|
||||||
|
'transition',
|
||||||
|
'transition-delay',
|
||||||
|
'transition-duration',
|
||||||
|
'transition-property',
|
||||||
|
'transition-timing-function',
|
||||||
|
'user-drag',
|
||||||
|
'user-modify',
|
||||||
|
'user-select',
|
||||||
|
'wrap',
|
||||||
|
'wrap-flow',
|
||||||
|
'wrap-margin',
|
||||||
|
'wrap-padding',
|
||||||
|
'wrap-shape-inside',
|
||||||
|
'wrap-shape-outside',
|
||||||
|
'wrap-through',
|
||||||
|
'writing-mode',
|
||||||
|
'zoom',
|
||||||
|
].map((prop) => 'webkit-' + prop);
|
||||||
|
|
@ -0,0 +1,6 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
module.exports.POSITION_AT_SHORTHAND = {
|
||||||
|
first: 0,
|
||||||
|
second: 1,
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,90 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
// autogenerated - 12/28/2023
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
* https://www.w3.org/Style/CSS/all-properties.en.html
|
||||||
|
*/
|
||||||
|
|
||||||
|
var implementedProperties = new Set();
|
||||||
|
implementedProperties.add("azimuth");
|
||||||
|
implementedProperties.add("background");
|
||||||
|
implementedProperties.add("background-attachment");
|
||||||
|
implementedProperties.add("background-color");
|
||||||
|
implementedProperties.add("background-image");
|
||||||
|
implementedProperties.add("background-position");
|
||||||
|
implementedProperties.add("background-repeat");
|
||||||
|
implementedProperties.add("border");
|
||||||
|
implementedProperties.add("border-bottom");
|
||||||
|
implementedProperties.add("border-bottom-color");
|
||||||
|
implementedProperties.add("border-bottom-style");
|
||||||
|
implementedProperties.add("border-bottom-width");
|
||||||
|
implementedProperties.add("border-collapse");
|
||||||
|
implementedProperties.add("border-color");
|
||||||
|
implementedProperties.add("border-left");
|
||||||
|
implementedProperties.add("border-left-color");
|
||||||
|
implementedProperties.add("border-left-style");
|
||||||
|
implementedProperties.add("border-left-width");
|
||||||
|
implementedProperties.add("border-right");
|
||||||
|
implementedProperties.add("border-right-color");
|
||||||
|
implementedProperties.add("border-right-style");
|
||||||
|
implementedProperties.add("border-right-width");
|
||||||
|
implementedProperties.add("border-spacing");
|
||||||
|
implementedProperties.add("border-style");
|
||||||
|
implementedProperties.add("border-top");
|
||||||
|
implementedProperties.add("border-top-color");
|
||||||
|
implementedProperties.add("border-top-style");
|
||||||
|
implementedProperties.add("border-top-width");
|
||||||
|
implementedProperties.add("border-width");
|
||||||
|
implementedProperties.add("bottom");
|
||||||
|
implementedProperties.add("clear");
|
||||||
|
implementedProperties.add("clip");
|
||||||
|
implementedProperties.add("color");
|
||||||
|
implementedProperties.add("css-float");
|
||||||
|
implementedProperties.add("flex");
|
||||||
|
implementedProperties.add("flex-basis");
|
||||||
|
implementedProperties.add("flex-grow");
|
||||||
|
implementedProperties.add("flex-shrink");
|
||||||
|
implementedProperties.add("float");
|
||||||
|
implementedProperties.add("flood-color");
|
||||||
|
implementedProperties.add("font");
|
||||||
|
implementedProperties.add("font-family");
|
||||||
|
implementedProperties.add("font-size");
|
||||||
|
implementedProperties.add("font-style");
|
||||||
|
implementedProperties.add("font-variant");
|
||||||
|
implementedProperties.add("font-weight");
|
||||||
|
implementedProperties.add("height");
|
||||||
|
implementedProperties.add("left");
|
||||||
|
implementedProperties.add("lighting-color");
|
||||||
|
implementedProperties.add("line-height");
|
||||||
|
implementedProperties.add("margin");
|
||||||
|
implementedProperties.add("margin-bottom");
|
||||||
|
implementedProperties.add("margin-left");
|
||||||
|
implementedProperties.add("margin-right");
|
||||||
|
implementedProperties.add("margin-top");
|
||||||
|
implementedProperties.add("opacity");
|
||||||
|
implementedProperties.add("outline-color");
|
||||||
|
implementedProperties.add("padding");
|
||||||
|
implementedProperties.add("padding-bottom");
|
||||||
|
implementedProperties.add("padding-left");
|
||||||
|
implementedProperties.add("padding-right");
|
||||||
|
implementedProperties.add("padding-top");
|
||||||
|
implementedProperties.add("right");
|
||||||
|
implementedProperties.add("stop-color");
|
||||||
|
implementedProperties.add("text-line-through-color");
|
||||||
|
implementedProperties.add("text-overline-color");
|
||||||
|
implementedProperties.add("text-underline-color");
|
||||||
|
implementedProperties.add("top");
|
||||||
|
implementedProperties.add("webkit-border-after-color");
|
||||||
|
implementedProperties.add("webkit-border-before-color");
|
||||||
|
implementedProperties.add("webkit-border-end-color");
|
||||||
|
implementedProperties.add("webkit-border-start-color");
|
||||||
|
implementedProperties.add("webkit-column-rule-color");
|
||||||
|
implementedProperties.add("webkit-match-nearest-mail-blockquote-color");
|
||||||
|
implementedProperties.add("webkit-tap-highlight-color");
|
||||||
|
implementedProperties.add("webkit-text-emphasis-color");
|
||||||
|
implementedProperties.add("webkit-text-fill-color");
|
||||||
|
implementedProperties.add("webkit-text-stroke-color");
|
||||||
|
implementedProperties.add("width");
|
||||||
|
module.exports = implementedProperties;
|
||||||
|
|
@ -0,0 +1,152 @@
|
||||||
|
[
|
||||||
|
"aliceblue",
|
||||||
|
"antiquewhite",
|
||||||
|
"aqua",
|
||||||
|
"aquamarine",
|
||||||
|
"azure",
|
||||||
|
"beige",
|
||||||
|
"bisque",
|
||||||
|
"black",
|
||||||
|
"blanchedalmond",
|
||||||
|
"blue",
|
||||||
|
"blueviolet",
|
||||||
|
"brown",
|
||||||
|
"burlywood",
|
||||||
|
"cadetblue",
|
||||||
|
"chartreuse",
|
||||||
|
"chocolate",
|
||||||
|
"coral",
|
||||||
|
"cornflowerblue",
|
||||||
|
"cornsilk",
|
||||||
|
"crimson",
|
||||||
|
"cyan",
|
||||||
|
"darkblue",
|
||||||
|
"darkcyan",
|
||||||
|
"darkgoldenrod",
|
||||||
|
"darkgray",
|
||||||
|
"darkgreen",
|
||||||
|
"darkgrey",
|
||||||
|
"darkkhaki",
|
||||||
|
"darkmagenta",
|
||||||
|
"darkolivegreen",
|
||||||
|
"darkorange",
|
||||||
|
"darkorchid",
|
||||||
|
"darkred",
|
||||||
|
"darksalmon",
|
||||||
|
"darkseagreen",
|
||||||
|
"darkslateblue",
|
||||||
|
"darkslategray",
|
||||||
|
"darkslategrey",
|
||||||
|
"darkturquoise",
|
||||||
|
"darkviolet",
|
||||||
|
"deeppink",
|
||||||
|
"deepskyblue",
|
||||||
|
"dimgray",
|
||||||
|
"dimgrey",
|
||||||
|
"dodgerblue",
|
||||||
|
"firebrick",
|
||||||
|
"floralwhite",
|
||||||
|
"forestgreen",
|
||||||
|
"fuchsia",
|
||||||
|
"gainsboro",
|
||||||
|
"ghostwhite",
|
||||||
|
"gold",
|
||||||
|
"goldenrod",
|
||||||
|
"gray",
|
||||||
|
"green",
|
||||||
|
"greenyellow",
|
||||||
|
"grey",
|
||||||
|
"honeydew",
|
||||||
|
"hotpink",
|
||||||
|
"indianred",
|
||||||
|
"indigo",
|
||||||
|
"ivory",
|
||||||
|
"khaki",
|
||||||
|
"lavender",
|
||||||
|
"lavenderblush",
|
||||||
|
"lawngreen",
|
||||||
|
"lemonchiffon",
|
||||||
|
"lightblue",
|
||||||
|
"lightcoral",
|
||||||
|
"lightcyan",
|
||||||
|
"lightgoldenrodyellow",
|
||||||
|
"lightgray",
|
||||||
|
"lightgreen",
|
||||||
|
"lightgrey",
|
||||||
|
"lightpink",
|
||||||
|
"lightsalmon",
|
||||||
|
"lightseagreen",
|
||||||
|
"lightskyblue",
|
||||||
|
"lightslategray",
|
||||||
|
"lightslategrey",
|
||||||
|
"lightsteelblue",
|
||||||
|
"lightyellow",
|
||||||
|
"lime",
|
||||||
|
"limegreen",
|
||||||
|
"linen",
|
||||||
|
"magenta",
|
||||||
|
"maroon",
|
||||||
|
"mediumaquamarine",
|
||||||
|
"mediumblue",
|
||||||
|
"mediumorchid",
|
||||||
|
"mediumpurple",
|
||||||
|
"mediumseagreen",
|
||||||
|
"mediumslateblue",
|
||||||
|
"mediumspringgreen",
|
||||||
|
"mediumturquoise",
|
||||||
|
"mediumvioletred",
|
||||||
|
"midnightblue",
|
||||||
|
"mintcream",
|
||||||
|
"mistyrose",
|
||||||
|
"moccasin",
|
||||||
|
"navajowhite",
|
||||||
|
"navy",
|
||||||
|
"oldlace",
|
||||||
|
"olive",
|
||||||
|
"olivedrab",
|
||||||
|
"orange",
|
||||||
|
"orangered",
|
||||||
|
"orchid",
|
||||||
|
"palegoldenrod",
|
||||||
|
"palegreen",
|
||||||
|
"paleturquoise",
|
||||||
|
"palevioletred",
|
||||||
|
"papayawhip",
|
||||||
|
"peachpuff",
|
||||||
|
"peru",
|
||||||
|
"pink",
|
||||||
|
"plum",
|
||||||
|
"powderblue",
|
||||||
|
"purple",
|
||||||
|
"rebeccapurple",
|
||||||
|
"red",
|
||||||
|
"rosybrown",
|
||||||
|
"royalblue",
|
||||||
|
"saddlebrown",
|
||||||
|
"salmon",
|
||||||
|
"sandybrown",
|
||||||
|
"seagreen",
|
||||||
|
"seashell",
|
||||||
|
"sienna",
|
||||||
|
"silver",
|
||||||
|
"skyblue",
|
||||||
|
"slateblue",
|
||||||
|
"slategray",
|
||||||
|
"slategrey",
|
||||||
|
"snow",
|
||||||
|
"springgreen",
|
||||||
|
"steelblue",
|
||||||
|
"tan",
|
||||||
|
"teal",
|
||||||
|
"thistle",
|
||||||
|
"tomato",
|
||||||
|
"turquoise",
|
||||||
|
"violet",
|
||||||
|
"wheat",
|
||||||
|
"white",
|
||||||
|
"whitesmoke",
|
||||||
|
"yellow",
|
||||||
|
"yellowgreen",
|
||||||
|
"transparent",
|
||||||
|
"currentcolor"
|
||||||
|
]
|
||||||
|
|
@ -0,0 +1,735 @@
|
||||||
|
/*********************************************************************
|
||||||
|
* These are commonly used parsers for CSS Values they take a string *
|
||||||
|
* to parse and return a string after it's been converted, if needed *
|
||||||
|
********************************************************************/
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
const namedColors = require('./named_colors.json');
|
||||||
|
const { hslToRgb } = require('./utils/colorSpace');
|
||||||
|
|
||||||
|
exports.TYPES = {
|
||||||
|
INTEGER: 1,
|
||||||
|
NUMBER: 2,
|
||||||
|
LENGTH: 3,
|
||||||
|
PERCENT: 4,
|
||||||
|
URL: 5,
|
||||||
|
COLOR: 6,
|
||||||
|
STRING: 7,
|
||||||
|
ANGLE: 8,
|
||||||
|
KEYWORD: 9,
|
||||||
|
NULL_OR_EMPTY_STR: 10,
|
||||||
|
CALC: 11,
|
||||||
|
};
|
||||||
|
|
||||||
|
// rough regular expressions
|
||||||
|
var integerRegEx = /^[-+]?[0-9]+$/;
|
||||||
|
var numberRegEx = /^[-+]?[0-9]*\.?[0-9]+$/;
|
||||||
|
var lengthRegEx = /^(0|[-+]?[0-9]*\.?[0-9]+(in|cm|em|mm|pt|pc|px|ex|rem|vh|vw|ch))$/;
|
||||||
|
var percentRegEx = /^[-+]?[0-9]*\.?[0-9]+%$/;
|
||||||
|
var urlRegEx = /^url\(\s*([^)]*)\s*\)$/;
|
||||||
|
var stringRegEx = /^("[^"]*"|'[^']*')$/;
|
||||||
|
var colorRegEx1 = /^#([0-9a-fA-F]{3,4}){1,2}$/;
|
||||||
|
var colorRegEx2 = /^rgb\(([^)]*)\)$/;
|
||||||
|
var colorRegEx3 = /^rgba\(([^)]*)\)$/;
|
||||||
|
var calcRegEx = /^calc\(([^)]*)\)$/;
|
||||||
|
var colorRegEx4 =
|
||||||
|
/^hsla?\(\s*(-?\d+|-?\d*.\d+)\s*,\s*(-?\d+|-?\d*.\d+)%\s*,\s*(-?\d+|-?\d*.\d+)%\s*(,\s*(-?\d+|-?\d*.\d+)\s*)?\)/;
|
||||||
|
var angleRegEx = /^([-+]?[0-9]*\.?[0-9]+)(deg|grad|rad)$/;
|
||||||
|
|
||||||
|
// This will return one of the above types based on the passed in string
|
||||||
|
exports.valueType = function valueType(val) {
|
||||||
|
if (val === '' || val === null) {
|
||||||
|
return exports.TYPES.NULL_OR_EMPTY_STR;
|
||||||
|
}
|
||||||
|
if (typeof val === 'number') {
|
||||||
|
val = val.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof val !== 'string') {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (integerRegEx.test(val)) {
|
||||||
|
return exports.TYPES.INTEGER;
|
||||||
|
}
|
||||||
|
if (numberRegEx.test(val)) {
|
||||||
|
return exports.TYPES.NUMBER;
|
||||||
|
}
|
||||||
|
if (lengthRegEx.test(val)) {
|
||||||
|
return exports.TYPES.LENGTH;
|
||||||
|
}
|
||||||
|
if (percentRegEx.test(val)) {
|
||||||
|
return exports.TYPES.PERCENT;
|
||||||
|
}
|
||||||
|
if (urlRegEx.test(val)) {
|
||||||
|
return exports.TYPES.URL;
|
||||||
|
}
|
||||||
|
if (calcRegEx.test(val)) {
|
||||||
|
return exports.TYPES.CALC;
|
||||||
|
}
|
||||||
|
if (stringRegEx.test(val)) {
|
||||||
|
return exports.TYPES.STRING;
|
||||||
|
}
|
||||||
|
if (angleRegEx.test(val)) {
|
||||||
|
return exports.TYPES.ANGLE;
|
||||||
|
}
|
||||||
|
if (colorRegEx1.test(val)) {
|
||||||
|
return exports.TYPES.COLOR;
|
||||||
|
}
|
||||||
|
|
||||||
|
var res = colorRegEx2.exec(val);
|
||||||
|
var parts;
|
||||||
|
if (res !== null) {
|
||||||
|
parts = res[1].split(/\s*,\s*/);
|
||||||
|
if (parts.length !== 3) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
if (
|
||||||
|
parts.every(percentRegEx.test.bind(percentRegEx)) ||
|
||||||
|
parts.every(integerRegEx.test.bind(integerRegEx))
|
||||||
|
) {
|
||||||
|
return exports.TYPES.COLOR;
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
res = colorRegEx3.exec(val);
|
||||||
|
if (res !== null) {
|
||||||
|
parts = res[1].split(/\s*,\s*/);
|
||||||
|
if (parts.length !== 4) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
if (
|
||||||
|
parts.slice(0, 3).every(percentRegEx.test.bind(percentRegEx)) ||
|
||||||
|
parts.slice(0, 3).every(integerRegEx.test.bind(integerRegEx))
|
||||||
|
) {
|
||||||
|
if (numberRegEx.test(parts[3])) {
|
||||||
|
return exports.TYPES.COLOR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (colorRegEx4.test(val)) {
|
||||||
|
return exports.TYPES.COLOR;
|
||||||
|
}
|
||||||
|
|
||||||
|
// could still be a color, one of the standard keyword colors
|
||||||
|
val = val.toLowerCase();
|
||||||
|
|
||||||
|
if (namedColors.includes(val)) {
|
||||||
|
return exports.TYPES.COLOR;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (val) {
|
||||||
|
// the following are deprecated in CSS3
|
||||||
|
case 'activeborder':
|
||||||
|
case 'activecaption':
|
||||||
|
case 'appworkspace':
|
||||||
|
case 'background':
|
||||||
|
case 'buttonface':
|
||||||
|
case 'buttonhighlight':
|
||||||
|
case 'buttonshadow':
|
||||||
|
case 'buttontext':
|
||||||
|
case 'captiontext':
|
||||||
|
case 'graytext':
|
||||||
|
case 'highlight':
|
||||||
|
case 'highlighttext':
|
||||||
|
case 'inactiveborder':
|
||||||
|
case 'inactivecaption':
|
||||||
|
case 'inactivecaptiontext':
|
||||||
|
case 'infobackground':
|
||||||
|
case 'infotext':
|
||||||
|
case 'menu':
|
||||||
|
case 'menutext':
|
||||||
|
case 'scrollbar':
|
||||||
|
case 'threeddarkshadow':
|
||||||
|
case 'threedface':
|
||||||
|
case 'threedhighlight':
|
||||||
|
case 'threedlightshadow':
|
||||||
|
case 'threedshadow':
|
||||||
|
case 'window':
|
||||||
|
case 'windowframe':
|
||||||
|
case 'windowtext':
|
||||||
|
return exports.TYPES.COLOR;
|
||||||
|
default:
|
||||||
|
return exports.TYPES.KEYWORD;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
exports.parseInteger = function parseInteger(val) {
|
||||||
|
var type = exports.valueType(val);
|
||||||
|
if (type === exports.TYPES.NULL_OR_EMPTY_STR) {
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
if (type !== exports.TYPES.INTEGER) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
return String(parseInt(val, 10));
|
||||||
|
};
|
||||||
|
|
||||||
|
exports.parseNumber = function parseNumber(val) {
|
||||||
|
var type = exports.valueType(val);
|
||||||
|
if (type === exports.TYPES.NULL_OR_EMPTY_STR) {
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
if (type !== exports.TYPES.NUMBER && type !== exports.TYPES.INTEGER) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
return String(parseFloat(val));
|
||||||
|
};
|
||||||
|
|
||||||
|
exports.parseLength = function parseLength(val) {
|
||||||
|
if (val === 0 || val === '0') {
|
||||||
|
return '0px';
|
||||||
|
}
|
||||||
|
var type = exports.valueType(val);
|
||||||
|
if (type === exports.TYPES.NULL_OR_EMPTY_STR) {
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
if (type !== exports.TYPES.LENGTH) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
return val;
|
||||||
|
};
|
||||||
|
|
||||||
|
exports.parsePercent = function parsePercent(val) {
|
||||||
|
if (val === 0 || val === '0') {
|
||||||
|
return '0%';
|
||||||
|
}
|
||||||
|
var type = exports.valueType(val);
|
||||||
|
if (type === exports.TYPES.NULL_OR_EMPTY_STR) {
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
if (type !== exports.TYPES.PERCENT) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
return val;
|
||||||
|
};
|
||||||
|
|
||||||
|
// either a length or a percent
|
||||||
|
exports.parseMeasurement = function parseMeasurement(val) {
|
||||||
|
var type = exports.valueType(val);
|
||||||
|
if (type === exports.TYPES.CALC) {
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
var length = exports.parseLength(val);
|
||||||
|
if (length !== undefined) {
|
||||||
|
return length;
|
||||||
|
}
|
||||||
|
return exports.parsePercent(val);
|
||||||
|
};
|
||||||
|
|
||||||
|
exports.parseUrl = function parseUrl(val) {
|
||||||
|
var type = exports.valueType(val);
|
||||||
|
if (type === exports.TYPES.NULL_OR_EMPTY_STR) {
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
var res = urlRegEx.exec(val);
|
||||||
|
// does it match the regex?
|
||||||
|
if (!res) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
var str = res[1];
|
||||||
|
// if it starts with single or double quotes, does it end with the same?
|
||||||
|
if ((str[0] === '"' || str[0] === "'") && str[0] !== str[str.length - 1]) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
if (str[0] === '"' || str[0] === "'") {
|
||||||
|
str = str.substr(1, str.length - 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
var i;
|
||||||
|
for (i = 0; i < str.length; i++) {
|
||||||
|
switch (str[i]) {
|
||||||
|
case '(':
|
||||||
|
case ')':
|
||||||
|
case ' ':
|
||||||
|
case '\t':
|
||||||
|
case '\n':
|
||||||
|
case "'":
|
||||||
|
case '"':
|
||||||
|
return undefined;
|
||||||
|
case '\\':
|
||||||
|
i++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 'url(' + str + ')';
|
||||||
|
};
|
||||||
|
|
||||||
|
exports.parseString = function parseString(val) {
|
||||||
|
var type = exports.valueType(val);
|
||||||
|
if (type === exports.TYPES.NULL_OR_EMPTY_STR) {
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
if (type !== exports.TYPES.STRING) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
var i;
|
||||||
|
for (i = 1; i < val.length - 1; i++) {
|
||||||
|
switch (val[i]) {
|
||||||
|
case val[0]:
|
||||||
|
return undefined;
|
||||||
|
case '\\':
|
||||||
|
i++;
|
||||||
|
while (i < val.length - 1 && /[0-9A-Fa-f]/.test(val[i])) {
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (i >= val.length) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
return val;
|
||||||
|
};
|
||||||
|
|
||||||
|
exports.parseColor = function parseColor(val) {
|
||||||
|
var type = exports.valueType(val);
|
||||||
|
if (type === exports.TYPES.NULL_OR_EMPTY_STR) {
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
var red,
|
||||||
|
green,
|
||||||
|
blue,
|
||||||
|
hue,
|
||||||
|
saturation,
|
||||||
|
lightness,
|
||||||
|
alpha = 1;
|
||||||
|
var parts;
|
||||||
|
var res = colorRegEx1.exec(val);
|
||||||
|
// is it #aaa, #ababab, #aaaa, #abababaa
|
||||||
|
if (res) {
|
||||||
|
var defaultHex = val.substr(1);
|
||||||
|
var hex = val.substr(1);
|
||||||
|
if (hex.length === 3 || hex.length === 4) {
|
||||||
|
hex = hex[0] + hex[0] + hex[1] + hex[1] + hex[2] + hex[2];
|
||||||
|
|
||||||
|
if (defaultHex.length === 4) {
|
||||||
|
hex = hex + defaultHex[3] + defaultHex[3];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
red = parseInt(hex.substr(0, 2), 16);
|
||||||
|
green = parseInt(hex.substr(2, 2), 16);
|
||||||
|
blue = parseInt(hex.substr(4, 2), 16);
|
||||||
|
if (hex.length === 8) {
|
||||||
|
var hexAlpha = hex.substr(6, 2);
|
||||||
|
var hexAlphaToRgbaAlpha = Number((parseInt(hexAlpha, 16) / 255).toFixed(3));
|
||||||
|
|
||||||
|
return 'rgba(' + red + ', ' + green + ', ' + blue + ', ' + hexAlphaToRgbaAlpha + ')';
|
||||||
|
}
|
||||||
|
return 'rgb(' + red + ', ' + green + ', ' + blue + ')';
|
||||||
|
}
|
||||||
|
|
||||||
|
res = colorRegEx2.exec(val);
|
||||||
|
if (res) {
|
||||||
|
parts = res[1].split(/\s*,\s*/);
|
||||||
|
if (parts.length !== 3) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
if (parts.every(percentRegEx.test.bind(percentRegEx))) {
|
||||||
|
red = Math.floor((parseFloat(parts[0].slice(0, -1)) * 255) / 100);
|
||||||
|
green = Math.floor((parseFloat(parts[1].slice(0, -1)) * 255) / 100);
|
||||||
|
blue = Math.floor((parseFloat(parts[2].slice(0, -1)) * 255) / 100);
|
||||||
|
} else if (parts.every(integerRegEx.test.bind(integerRegEx))) {
|
||||||
|
red = parseInt(parts[0], 10);
|
||||||
|
green = parseInt(parts[1], 10);
|
||||||
|
blue = parseInt(parts[2], 10);
|
||||||
|
} else {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
red = Math.min(255, Math.max(0, red));
|
||||||
|
green = Math.min(255, Math.max(0, green));
|
||||||
|
blue = Math.min(255, Math.max(0, blue));
|
||||||
|
return 'rgb(' + red + ', ' + green + ', ' + blue + ')';
|
||||||
|
}
|
||||||
|
|
||||||
|
res = colorRegEx3.exec(val);
|
||||||
|
if (res) {
|
||||||
|
parts = res[1].split(/\s*,\s*/);
|
||||||
|
if (parts.length !== 4) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
if (parts.slice(0, 3).every(percentRegEx.test.bind(percentRegEx))) {
|
||||||
|
red = Math.floor((parseFloat(parts[0].slice(0, -1)) * 255) / 100);
|
||||||
|
green = Math.floor((parseFloat(parts[1].slice(0, -1)) * 255) / 100);
|
||||||
|
blue = Math.floor((parseFloat(parts[2].slice(0, -1)) * 255) / 100);
|
||||||
|
alpha = parseFloat(parts[3]);
|
||||||
|
} else if (parts.slice(0, 3).every(integerRegEx.test.bind(integerRegEx))) {
|
||||||
|
red = parseInt(parts[0], 10);
|
||||||
|
green = parseInt(parts[1], 10);
|
||||||
|
blue = parseInt(parts[2], 10);
|
||||||
|
alpha = parseFloat(parts[3]);
|
||||||
|
} else {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
if (isNaN(alpha)) {
|
||||||
|
alpha = 1;
|
||||||
|
}
|
||||||
|
red = Math.min(255, Math.max(0, red));
|
||||||
|
green = Math.min(255, Math.max(0, green));
|
||||||
|
blue = Math.min(255, Math.max(0, blue));
|
||||||
|
alpha = Math.min(1, Math.max(0, alpha));
|
||||||
|
if (alpha === 1) {
|
||||||
|
return 'rgb(' + red + ', ' + green + ', ' + blue + ')';
|
||||||
|
}
|
||||||
|
return 'rgba(' + red + ', ' + green + ', ' + blue + ', ' + alpha + ')';
|
||||||
|
}
|
||||||
|
|
||||||
|
res = colorRegEx4.exec(val);
|
||||||
|
if (res) {
|
||||||
|
const [, _hue, _saturation, _lightness, _alphaString = ''] = res;
|
||||||
|
const _alpha = parseFloat(_alphaString.replace(',', '').trim());
|
||||||
|
if (!_hue || !_saturation || !_lightness) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
hue = parseFloat(_hue);
|
||||||
|
saturation = parseInt(_saturation, 10);
|
||||||
|
lightness = parseInt(_lightness, 10);
|
||||||
|
if (_alpha && numberRegEx.test(_alpha)) {
|
||||||
|
alpha = parseFloat(_alpha);
|
||||||
|
}
|
||||||
|
|
||||||
|
const [r, g, b] = hslToRgb(hue, saturation / 100, lightness / 100);
|
||||||
|
if (!_alphaString || alpha === 1) {
|
||||||
|
return 'rgb(' + r + ', ' + g + ', ' + b + ')';
|
||||||
|
}
|
||||||
|
return 'rgba(' + r + ', ' + g + ', ' + b + ', ' + alpha + ')';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type === exports.TYPES.COLOR) {
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
|
};
|
||||||
|
|
||||||
|
exports.parseAngle = function parseAngle(val) {
|
||||||
|
var type = exports.valueType(val);
|
||||||
|
if (type === exports.TYPES.NULL_OR_EMPTY_STR) {
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
if (type !== exports.TYPES.ANGLE) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
var res = angleRegEx.exec(val);
|
||||||
|
var flt = parseFloat(res[1]);
|
||||||
|
if (res[2] === 'rad') {
|
||||||
|
flt *= 180 / Math.PI;
|
||||||
|
} else if (res[2] === 'grad') {
|
||||||
|
flt *= 360 / 400;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (flt < 0) {
|
||||||
|
flt += 360;
|
||||||
|
}
|
||||||
|
while (flt > 360) {
|
||||||
|
flt -= 360;
|
||||||
|
}
|
||||||
|
return flt + 'deg';
|
||||||
|
};
|
||||||
|
|
||||||
|
exports.parseKeyword = function parseKeyword(val, valid_keywords) {
|
||||||
|
var type = exports.valueType(val);
|
||||||
|
if (type === exports.TYPES.NULL_OR_EMPTY_STR) {
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
if (type !== exports.TYPES.KEYWORD) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
val = val.toString().toLowerCase();
|
||||||
|
var i;
|
||||||
|
for (i = 0; i < valid_keywords.length; i++) {
|
||||||
|
if (valid_keywords[i].toLowerCase() === val) {
|
||||||
|
return valid_keywords[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
|
};
|
||||||
|
|
||||||
|
// utility to translate from border-width to borderWidth
|
||||||
|
var dashedToCamelCase = function (dashed) {
|
||||||
|
var i;
|
||||||
|
var camel = '';
|
||||||
|
var nextCap = false;
|
||||||
|
for (i = 0; i < dashed.length; i++) {
|
||||||
|
if (dashed[i] !== '-') {
|
||||||
|
camel += nextCap ? dashed[i].toUpperCase() : dashed[i];
|
||||||
|
nextCap = false;
|
||||||
|
} else {
|
||||||
|
nextCap = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return camel;
|
||||||
|
};
|
||||||
|
exports.dashedToCamelCase = dashedToCamelCase;
|
||||||
|
|
||||||
|
var is_space = /\s/;
|
||||||
|
var opening_deliminators = ['"', "'", '('];
|
||||||
|
var closing_deliminators = ['"', "'", ')'];
|
||||||
|
// this splits on whitespace, but keeps quoted and parened parts together
|
||||||
|
var getParts = function (str) {
|
||||||
|
var deliminator_stack = [];
|
||||||
|
var length = str.length;
|
||||||
|
var i;
|
||||||
|
var parts = [];
|
||||||
|
var current_part = '';
|
||||||
|
var opening_index;
|
||||||
|
var closing_index;
|
||||||
|
for (i = 0; i < length; i++) {
|
||||||
|
opening_index = opening_deliminators.indexOf(str[i]);
|
||||||
|
closing_index = closing_deliminators.indexOf(str[i]);
|
||||||
|
if (is_space.test(str[i])) {
|
||||||
|
if (deliminator_stack.length === 0) {
|
||||||
|
if (current_part !== '') {
|
||||||
|
parts.push(current_part);
|
||||||
|
}
|
||||||
|
current_part = '';
|
||||||
|
} else {
|
||||||
|
current_part += str[i];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (str[i] === '\\') {
|
||||||
|
i++;
|
||||||
|
current_part += str[i];
|
||||||
|
} else {
|
||||||
|
current_part += str[i];
|
||||||
|
if (
|
||||||
|
closing_index !== -1 &&
|
||||||
|
closing_index === deliminator_stack[deliminator_stack.length - 1]
|
||||||
|
) {
|
||||||
|
deliminator_stack.pop();
|
||||||
|
} else if (opening_index !== -1) {
|
||||||
|
deliminator_stack.push(opening_index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (current_part !== '') {
|
||||||
|
parts.push(current_part);
|
||||||
|
}
|
||||||
|
return parts;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* this either returns undefined meaning that it isn't valid
|
||||||
|
* or returns an object where the keys are dashed short
|
||||||
|
* hand properties and the values are the values to set
|
||||||
|
* on them
|
||||||
|
*/
|
||||||
|
exports.shorthandParser = function parse(v, shorthand_for) {
|
||||||
|
var obj = {};
|
||||||
|
var type = exports.valueType(v);
|
||||||
|
if (type === exports.TYPES.NULL_OR_EMPTY_STR) {
|
||||||
|
Object.keys(shorthand_for).forEach(function (property) {
|
||||||
|
obj[property] = '';
|
||||||
|
});
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof v === 'number') {
|
||||||
|
v = v.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof v !== 'string') {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (v.toLowerCase() === 'inherit') {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
var parts = getParts(v);
|
||||||
|
var valid = true;
|
||||||
|
parts.forEach(function (part, i) {
|
||||||
|
var part_valid = false;
|
||||||
|
Object.keys(shorthand_for).forEach(function (property) {
|
||||||
|
if (shorthand_for[property].isValid(part, i)) {
|
||||||
|
part_valid = true;
|
||||||
|
obj[property] = part;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
valid = valid && part_valid;
|
||||||
|
});
|
||||||
|
if (!valid) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
return obj;
|
||||||
|
};
|
||||||
|
|
||||||
|
exports.shorthandSetter = function (property, shorthand_for) {
|
||||||
|
return function (v) {
|
||||||
|
var obj = exports.shorthandParser(v, shorthand_for);
|
||||||
|
if (obj === undefined) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
//console.log('shorthandSetter for:', property, 'obj:', obj);
|
||||||
|
Object.keys(obj).forEach(function (subprop) {
|
||||||
|
// in case subprop is an implicit property, this will clear
|
||||||
|
// *its* subpropertiesX
|
||||||
|
var camel = dashedToCamelCase(subprop);
|
||||||
|
this[camel] = obj[subprop];
|
||||||
|
// in case it gets translated into something else (0 -> 0px)
|
||||||
|
obj[subprop] = this[camel];
|
||||||
|
this.removeProperty(subprop);
|
||||||
|
// don't add in empty properties
|
||||||
|
if (obj[subprop] !== '') {
|
||||||
|
this._values[subprop] = obj[subprop];
|
||||||
|
}
|
||||||
|
}, this);
|
||||||
|
Object.keys(shorthand_for).forEach(function (subprop) {
|
||||||
|
if (!obj.hasOwnProperty(subprop)) {
|
||||||
|
this.removeProperty(subprop);
|
||||||
|
delete this._values[subprop];
|
||||||
|
}
|
||||||
|
}, this);
|
||||||
|
// in case the value is something like 'none' that removes all values,
|
||||||
|
// check that the generated one is not empty, first remove the property
|
||||||
|
// if it already exists, then call the shorthandGetter, if it's an empty
|
||||||
|
// string, don't set the property
|
||||||
|
this.removeProperty(property);
|
||||||
|
var calculated = exports.shorthandGetter(property, shorthand_for).call(this);
|
||||||
|
if (calculated !== '') {
|
||||||
|
this._setProperty(property, calculated);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
exports.shorthandGetter = function (property, shorthand_for) {
|
||||||
|
return function () {
|
||||||
|
if (this._values[property] !== undefined) {
|
||||||
|
return this.getPropertyValue(property);
|
||||||
|
}
|
||||||
|
return Object.keys(shorthand_for)
|
||||||
|
.map(function (subprop) {
|
||||||
|
return this.getPropertyValue(subprop);
|
||||||
|
}, this)
|
||||||
|
.filter(function (value) {
|
||||||
|
return value !== '';
|
||||||
|
})
|
||||||
|
.join(' ');
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
// isValid(){1,4} | inherit
|
||||||
|
// if one, it applies to all
|
||||||
|
// if two, the first applies to the top and bottom, and the second to left and right
|
||||||
|
// if three, the first applies to the top, the second to left and right, the third bottom
|
||||||
|
// if four, top, right, bottom, left
|
||||||
|
exports.implicitSetter = function (property_before, property_after, isValid, parser) {
|
||||||
|
property_after = property_after || '';
|
||||||
|
if (property_after !== '') {
|
||||||
|
property_after = '-' + property_after;
|
||||||
|
}
|
||||||
|
var part_names = ['top', 'right', 'bottom', 'left'];
|
||||||
|
|
||||||
|
return function (v) {
|
||||||
|
if (typeof v === 'number') {
|
||||||
|
v = v.toString();
|
||||||
|
}
|
||||||
|
if (typeof v !== 'string') {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
var parts;
|
||||||
|
if (v.toLowerCase() === 'inherit' || v === '') {
|
||||||
|
parts = [v];
|
||||||
|
} else {
|
||||||
|
parts = getParts(v);
|
||||||
|
}
|
||||||
|
if (parts.length < 1 || parts.length > 4) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!parts.every(isValid)) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
parts = parts.map(function (part) {
|
||||||
|
return parser(part);
|
||||||
|
});
|
||||||
|
this._setProperty(property_before + property_after, parts.join(' '));
|
||||||
|
if (parts.length === 1) {
|
||||||
|
parts[1] = parts[0];
|
||||||
|
}
|
||||||
|
if (parts.length === 2) {
|
||||||
|
parts[2] = parts[0];
|
||||||
|
}
|
||||||
|
if (parts.length === 3) {
|
||||||
|
parts[3] = parts[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var i = 0; i < 4; i++) {
|
||||||
|
var property = property_before + '-' + part_names[i] + property_after;
|
||||||
|
this.removeProperty(property);
|
||||||
|
if (parts[i] !== '') {
|
||||||
|
this._values[property] = parts[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return v;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
//
|
||||||
|
// Companion to implicitSetter, but for the individual parts.
|
||||||
|
// This sets the individual value, and checks to see if all four
|
||||||
|
// sub-parts are set. If so, it sets the shorthand version and removes
|
||||||
|
// the individual parts from the cssText.
|
||||||
|
//
|
||||||
|
exports.subImplicitSetter = function (prefix, part, isValid, parser) {
|
||||||
|
var property = prefix + '-' + part;
|
||||||
|
var subparts = [prefix + '-top', prefix + '-right', prefix + '-bottom', prefix + '-left'];
|
||||||
|
|
||||||
|
return function (v) {
|
||||||
|
if (typeof v === 'number') {
|
||||||
|
v = v.toString();
|
||||||
|
}
|
||||||
|
if (v === null) {
|
||||||
|
v = '';
|
||||||
|
}
|
||||||
|
if (typeof v !== 'string') {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
if (!isValid(v)) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
v = parser(v);
|
||||||
|
this._setProperty(property, v);
|
||||||
|
|
||||||
|
var combinedPriority = this.getPropertyPriority(prefix);
|
||||||
|
var parts = subparts.map((subpart) => this._values[subpart]);
|
||||||
|
var priorities = subparts.map((subpart) => this.getPropertyPriority(subpart));
|
||||||
|
// Combine into a single property if all values are set and have the same priority
|
||||||
|
if (
|
||||||
|
parts.every((p) => p !== '' && p != null) &&
|
||||||
|
priorities.every((p) => p === priorities[0]) &&
|
||||||
|
priorities[0] === combinedPriority
|
||||||
|
) {
|
||||||
|
for (var i = 0; i < subparts.length; i++) {
|
||||||
|
this.removeProperty(subparts[i]);
|
||||||
|
this._values[subparts[i]] = parts[i];
|
||||||
|
}
|
||||||
|
this._setProperty(prefix, parts.join(' '), priorities[0]);
|
||||||
|
} else {
|
||||||
|
this.removeProperty(prefix);
|
||||||
|
for (var j = 0; j < subparts.length; j++) {
|
||||||
|
// The property we're setting won't be important, the rest will either keep their priority or inherit it from the combined property
|
||||||
|
var priority = subparts[j] === property ? '' : priorities[j] || combinedPriority;
|
||||||
|
this._setProperty(subparts[j], parts[j], priority);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return v;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
var camel_to_dashed = /[A-Z]/g;
|
||||||
|
var first_segment = /^\([^-]\)-/;
|
||||||
|
var vendor_prefixes = ['o', 'moz', 'ms', 'webkit'];
|
||||||
|
exports.camelToDashed = function (camel_case) {
|
||||||
|
var match;
|
||||||
|
var dashed = camel_case.replace(camel_to_dashed, '-$&').toLowerCase();
|
||||||
|
match = dashed.match(first_segment);
|
||||||
|
if (match && vendor_prefixes.indexOf(match[1]) !== -1) {
|
||||||
|
dashed = '-' + dashed;
|
||||||
|
}
|
||||||
|
return dashed;
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,146 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
const parsers = require('./parsers');
|
||||||
|
|
||||||
|
describe('valueType', () => {
|
||||||
|
it('returns color for red', () => {
|
||||||
|
let input = 'red';
|
||||||
|
let output = parsers.valueType(input);
|
||||||
|
|
||||||
|
expect(output).toEqual(parsers.TYPES.COLOR);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('returns color for #nnnnnn', () => {
|
||||||
|
let input = '#fefefe';
|
||||||
|
let output = parsers.valueType(input);
|
||||||
|
|
||||||
|
expect(output).toEqual(parsers.TYPES.COLOR);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('returns color for rgb(n, n, n)', () => {
|
||||||
|
let input = 'rgb(10, 10, 10)';
|
||||||
|
let output = parsers.valueType(input);
|
||||||
|
|
||||||
|
expect(output).toEqual(parsers.TYPES.COLOR);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('returns color for rgb(p, p, p)', () => {
|
||||||
|
let input = 'rgb(10%, 10%, 10%)';
|
||||||
|
let output = parsers.valueType(input);
|
||||||
|
|
||||||
|
expect(output).toEqual(parsers.TYPES.COLOR);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('returns color for rgba(n, n, n, n)', () => {
|
||||||
|
let input = 'rgba(10, 10, 10, 1)';
|
||||||
|
let output = parsers.valueType(input);
|
||||||
|
|
||||||
|
expect(output).toEqual(parsers.TYPES.COLOR);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('returns color for rgba(n, n, n, n) with decimal alpha', () => {
|
||||||
|
let input = 'rgba(10, 10, 10, 0.5)';
|
||||||
|
let output = parsers.valueType(input);
|
||||||
|
|
||||||
|
expect(output).toEqual(parsers.TYPES.COLOR);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('returns color for rgba(p, p, p, n)', () => {
|
||||||
|
let input = 'rgba(10%, 10%, 10%, 1)';
|
||||||
|
let output = parsers.valueType(input);
|
||||||
|
|
||||||
|
expect(output).toEqual(parsers.TYPES.COLOR);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('returns color for rgba(p, p, p, n) with decimal alpha', () => {
|
||||||
|
let input = 'rgba(10%, 10%, 10%, 0.5)';
|
||||||
|
let output = parsers.valueType(input);
|
||||||
|
|
||||||
|
expect(output).toEqual(parsers.TYPES.COLOR);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('returns length for 100ch', () => {
|
||||||
|
let input = '100ch';
|
||||||
|
let output = parsers.valueType(input);
|
||||||
|
|
||||||
|
expect(output).toEqual(parsers.TYPES.LENGTH);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('returns calc from calc(100px * 2)', () => {
|
||||||
|
let input = 'calc(100px * 2)';
|
||||||
|
let output = parsers.valueType(input);
|
||||||
|
|
||||||
|
expect(output).toEqual(parsers.TYPES.CALC);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
describe('parseInteger', () => {
|
||||||
|
it.todo('test');
|
||||||
|
});
|
||||||
|
describe('parseNumber', () => {
|
||||||
|
it.todo('test');
|
||||||
|
});
|
||||||
|
describe('parseLength', () => {
|
||||||
|
it.todo('test');
|
||||||
|
});
|
||||||
|
describe('parsePercent', () => {
|
||||||
|
it.todo('test');
|
||||||
|
});
|
||||||
|
describe('parseMeasurement', () => {
|
||||||
|
it.todo('test');
|
||||||
|
});
|
||||||
|
describe('parseUrl', () => {
|
||||||
|
it.todo('test');
|
||||||
|
});
|
||||||
|
describe('parseString', () => {
|
||||||
|
it.todo('test');
|
||||||
|
});
|
||||||
|
describe('parseColor', () => {
|
||||||
|
it('should convert hsl to rgb values', () => {
|
||||||
|
let input = 'hsla(0, 1%, 2%)';
|
||||||
|
let output = parsers.parseColor(input);
|
||||||
|
|
||||||
|
expect(output).toEqual('rgb(5, 5, 5)');
|
||||||
|
});
|
||||||
|
it('should convert hsla to rgba values', () => {
|
||||||
|
let input = 'hsla(0, 1%, 2%, 0.5)';
|
||||||
|
let output = parsers.parseColor(input);
|
||||||
|
|
||||||
|
expect(output).toEqual('rgba(5, 5, 5, 0.5)');
|
||||||
|
});
|
||||||
|
it.each([
|
||||||
|
[120, 'rgb(0, 255, 0)'],
|
||||||
|
[240, 'rgb(0, 0, 255)'],
|
||||||
|
])('should convert not zero hsl with non zero hue %s to %s', (hue, rgbValue) => {
|
||||||
|
let input = 'hsl(' + hue + ', 100%, 50%)';
|
||||||
|
let output = parsers.parseColor(input);
|
||||||
|
expect(output).toEqual(rgbValue);
|
||||||
|
});
|
||||||
|
it.todo('Add more tests');
|
||||||
|
});
|
||||||
|
describe('parseAngle', () => {
|
||||||
|
it.todo('test');
|
||||||
|
});
|
||||||
|
describe('parseKeyword', () => {
|
||||||
|
it.todo('test');
|
||||||
|
});
|
||||||
|
describe('dashedToCamelCase', () => {
|
||||||
|
it.todo('test');
|
||||||
|
});
|
||||||
|
describe('shorthandParser', () => {
|
||||||
|
it.todo('test');
|
||||||
|
});
|
||||||
|
describe('shorthandSetter', () => {
|
||||||
|
it.todo('test');
|
||||||
|
});
|
||||||
|
describe('shorthandGetter', () => {
|
||||||
|
it.todo('test');
|
||||||
|
});
|
||||||
|
describe('implicitSetter', () => {
|
||||||
|
it.todo('test');
|
||||||
|
});
|
||||||
|
describe('subImplicitSetter', () => {
|
||||||
|
it.todo('test');
|
||||||
|
});
|
||||||
|
describe('camelToDashed', () => {
|
||||||
|
it.todo('test');
|
||||||
|
});
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,64 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var parsers = require('../parsers');
|
||||||
|
|
||||||
|
module.exports.definition = {
|
||||||
|
set: function (v) {
|
||||||
|
var valueType = parsers.valueType(v);
|
||||||
|
if (valueType === parsers.TYPES.ANGLE) {
|
||||||
|
return this._setProperty('azimuth', parsers.parseAngle(v));
|
||||||
|
}
|
||||||
|
if (valueType === parsers.TYPES.KEYWORD) {
|
||||||
|
var keywords = v.toLowerCase().trim().split(/\s+/);
|
||||||
|
var hasBehind = false;
|
||||||
|
if (keywords.length > 2) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var behindIndex = keywords.indexOf('behind');
|
||||||
|
hasBehind = behindIndex !== -1;
|
||||||
|
|
||||||
|
if (keywords.length === 2) {
|
||||||
|
if (!hasBehind) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
keywords.splice(behindIndex, 1);
|
||||||
|
}
|
||||||
|
if (keywords[0] === 'leftwards' || keywords[0] === 'rightwards') {
|
||||||
|
if (hasBehind) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
return this._setProperty('azimuth', keywords[0]);
|
||||||
|
}
|
||||||
|
if (keywords[0] === 'behind') {
|
||||||
|
return this._setProperty('azimuth', '180deg');
|
||||||
|
}
|
||||||
|
switch (keywords[0]) {
|
||||||
|
case 'left-side':
|
||||||
|
return this._setProperty('azimuth', '270deg');
|
||||||
|
case 'far-left':
|
||||||
|
return this._setProperty('azimuth', (hasBehind ? 240 : 300) + 'deg');
|
||||||
|
case 'left':
|
||||||
|
return this._setProperty('azimuth', (hasBehind ? 220 : 320) + 'deg');
|
||||||
|
case 'center-left':
|
||||||
|
return this._setProperty('azimuth', (hasBehind ? 200 : 340) + 'deg');
|
||||||
|
case 'center':
|
||||||
|
return this._setProperty('azimuth', (hasBehind ? 180 : 0) + 'deg');
|
||||||
|
case 'center-right':
|
||||||
|
return this._setProperty('azimuth', (hasBehind ? 160 : 20) + 'deg');
|
||||||
|
case 'right':
|
||||||
|
return this._setProperty('azimuth', (hasBehind ? 140 : 40) + 'deg');
|
||||||
|
case 'far-right':
|
||||||
|
return this._setProperty('azimuth', (hasBehind ? 120 : 60) + 'deg');
|
||||||
|
case 'right-side':
|
||||||
|
return this._setProperty('azimuth', '90deg');
|
||||||
|
default:
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
get: function () {
|
||||||
|
return this.getPropertyValue('azimuth');
|
||||||
|
},
|
||||||
|
enumerable: true,
|
||||||
|
configurable: true,
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,19 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var shorthandSetter = require('../parsers').shorthandSetter;
|
||||||
|
var shorthandGetter = require('../parsers').shorthandGetter;
|
||||||
|
|
||||||
|
var shorthand_for = {
|
||||||
|
'background-color': require('./backgroundColor'),
|
||||||
|
'background-image': require('./backgroundImage'),
|
||||||
|
'background-repeat': require('./backgroundRepeat'),
|
||||||
|
'background-attachment': require('./backgroundAttachment'),
|
||||||
|
'background-position': require('./backgroundPosition'),
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports.definition = {
|
||||||
|
set: shorthandSetter('background', shorthand_for),
|
||||||
|
get: shorthandGetter('background', shorthand_for),
|
||||||
|
enumerable: true,
|
||||||
|
configurable: true,
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,24 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var parsers = require('../parsers');
|
||||||
|
|
||||||
|
var isValid = (module.exports.isValid = function isValid(v) {
|
||||||
|
return (
|
||||||
|
parsers.valueType(v) === parsers.TYPES.KEYWORD &&
|
||||||
|
(v.toLowerCase() === 'scroll' || v.toLowerCase() === 'fixed' || v.toLowerCase() === 'inherit')
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
module.exports.definition = {
|
||||||
|
set: function (v) {
|
||||||
|
if (!isValid(v)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this._setProperty('background-attachment', v);
|
||||||
|
},
|
||||||
|
get: function () {
|
||||||
|
return this.getPropertyValue('background-attachment');
|
||||||
|
},
|
||||||
|
enumerable: true,
|
||||||
|
configurable: true,
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,36 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var parsers = require('../parsers');
|
||||||
|
|
||||||
|
var parse = function parse(v) {
|
||||||
|
var parsed = parsers.parseColor(v);
|
||||||
|
if (parsed !== undefined) {
|
||||||
|
return parsed;
|
||||||
|
}
|
||||||
|
if (
|
||||||
|
parsers.valueType(v) === parsers.TYPES.KEYWORD &&
|
||||||
|
(v.toLowerCase() === 'transparent' || v.toLowerCase() === 'inherit')
|
||||||
|
) {
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports.isValid = function isValid(v) {
|
||||||
|
return parse(v) !== undefined;
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports.definition = {
|
||||||
|
set: function (v) {
|
||||||
|
var parsed = parse(v);
|
||||||
|
if (parsed === undefined) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this._setProperty('background-color', parsed);
|
||||||
|
},
|
||||||
|
get: function () {
|
||||||
|
return this.getPropertyValue('background-color');
|
||||||
|
},
|
||||||
|
enumerable: true,
|
||||||
|
configurable: true,
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,32 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var parsers = require('../parsers');
|
||||||
|
|
||||||
|
var parse = function parse(v) {
|
||||||
|
var parsed = parsers.parseUrl(v);
|
||||||
|
if (parsed !== undefined) {
|
||||||
|
return parsed;
|
||||||
|
}
|
||||||
|
if (
|
||||||
|
parsers.valueType(v) === parsers.TYPES.KEYWORD &&
|
||||||
|
(v.toLowerCase() === 'none' || v.toLowerCase() === 'inherit')
|
||||||
|
) {
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports.isValid = function isValid(v) {
|
||||||
|
return parse(v) !== undefined;
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports.definition = {
|
||||||
|
set: function (v) {
|
||||||
|
this._setProperty('background-image', parse(v));
|
||||||
|
},
|
||||||
|
get: function () {
|
||||||
|
return this.getPropertyValue('background-image');
|
||||||
|
},
|
||||||
|
enumerable: true,
|
||||||
|
configurable: true,
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,58 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var parsers = require('../parsers');
|
||||||
|
|
||||||
|
var valid_keywords = ['top', 'center', 'bottom', 'left', 'right'];
|
||||||
|
|
||||||
|
var parse = function parse(v) {
|
||||||
|
if (v === '' || v === null) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
var parts = v.split(/\s+/);
|
||||||
|
if (parts.length > 2 || parts.length < 1) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
var types = [];
|
||||||
|
parts.forEach(function (part, index) {
|
||||||
|
types[index] = parsers.valueType(part);
|
||||||
|
});
|
||||||
|
if (parts.length === 1) {
|
||||||
|
if (types[0] === parsers.TYPES.LENGTH || types[0] === parsers.TYPES.PERCENT) {
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
if (types[0] === parsers.TYPES.KEYWORD) {
|
||||||
|
if (valid_keywords.indexOf(v.toLowerCase()) !== -1 || v.toLowerCase() === 'inherit') {
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
if (
|
||||||
|
(types[0] === parsers.TYPES.LENGTH || types[0] === parsers.TYPES.PERCENT) &&
|
||||||
|
(types[1] === parsers.TYPES.LENGTH || types[1] === parsers.TYPES.PERCENT)
|
||||||
|
) {
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
if (types[0] !== parsers.TYPES.KEYWORD || types[1] !== parsers.TYPES.KEYWORD) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
if (valid_keywords.indexOf(parts[0]) !== -1 && valid_keywords.indexOf(parts[1]) !== -1) {
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports.isValid = function isValid(v) {
|
||||||
|
return parse(v) !== undefined;
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports.definition = {
|
||||||
|
set: function (v) {
|
||||||
|
this._setProperty('background-position', parse(v));
|
||||||
|
},
|
||||||
|
get: function () {
|
||||||
|
return this.getPropertyValue('background-position');
|
||||||
|
},
|
||||||
|
enumerable: true,
|
||||||
|
configurable: true,
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,32 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var parsers = require('../parsers');
|
||||||
|
|
||||||
|
var parse = function parse(v) {
|
||||||
|
if (
|
||||||
|
parsers.valueType(v) === parsers.TYPES.KEYWORD &&
|
||||||
|
(v.toLowerCase() === 'repeat' ||
|
||||||
|
v.toLowerCase() === 'repeat-x' ||
|
||||||
|
v.toLowerCase() === 'repeat-y' ||
|
||||||
|
v.toLowerCase() === 'no-repeat' ||
|
||||||
|
v.toLowerCase() === 'inherit')
|
||||||
|
) {
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports.isValid = function isValid(v) {
|
||||||
|
return parse(v) !== undefined;
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports.definition = {
|
||||||
|
set: function (v) {
|
||||||
|
this._setProperty('background-repeat', parse(v));
|
||||||
|
},
|
||||||
|
get: function () {
|
||||||
|
return this.getPropertyValue('background-repeat');
|
||||||
|
},
|
||||||
|
enumerable: true,
|
||||||
|
configurable: true,
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,33 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var shorthandSetter = require('../parsers').shorthandSetter;
|
||||||
|
var shorthandGetter = require('../parsers').shorthandGetter;
|
||||||
|
|
||||||
|
var shorthand_for = {
|
||||||
|
'border-width': require('./borderWidth'),
|
||||||
|
'border-style': require('./borderStyle'),
|
||||||
|
'border-color': require('./borderColor'),
|
||||||
|
};
|
||||||
|
|
||||||
|
var myShorthandSetter = shorthandSetter('border', shorthand_for);
|
||||||
|
var myShorthandGetter = shorthandGetter('border', shorthand_for);
|
||||||
|
|
||||||
|
module.exports.definition = {
|
||||||
|
set: function (v) {
|
||||||
|
if (v.toString().toLowerCase() === 'none') {
|
||||||
|
v = '';
|
||||||
|
}
|
||||||
|
myShorthandSetter.call(this, v);
|
||||||
|
this.removeProperty('border-top');
|
||||||
|
this.removeProperty('border-left');
|
||||||
|
this.removeProperty('border-right');
|
||||||
|
this.removeProperty('border-bottom');
|
||||||
|
this._values['border-top'] = this._values.border;
|
||||||
|
this._values['border-left'] = this._values.border;
|
||||||
|
this._values['border-right'] = this._values.border;
|
||||||
|
this._values['border-bottom'] = this._values.border;
|
||||||
|
},
|
||||||
|
get: myShorthandGetter,
|
||||||
|
enumerable: true,
|
||||||
|
configurable: true,
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,17 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var shorthandSetter = require('../parsers').shorthandSetter;
|
||||||
|
var shorthandGetter = require('../parsers').shorthandGetter;
|
||||||
|
|
||||||
|
var shorthand_for = {
|
||||||
|
'border-bottom-width': require('./borderBottomWidth'),
|
||||||
|
'border-bottom-style': require('./borderBottomStyle'),
|
||||||
|
'border-bottom-color': require('./borderBottomColor'),
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports.definition = {
|
||||||
|
set: shorthandSetter('border-bottom', shorthand_for),
|
||||||
|
get: shorthandGetter('border-bottom', shorthand_for),
|
||||||
|
enumerable: true,
|
||||||
|
configurable: true,
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,16 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var isValid = (module.exports.isValid = require('./borderColor').isValid);
|
||||||
|
|
||||||
|
module.exports.definition = {
|
||||||
|
set: function (v) {
|
||||||
|
if (isValid(v)) {
|
||||||
|
this._setProperty('border-bottom-color', v);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
get: function () {
|
||||||
|
return this.getPropertyValue('border-bottom-color');
|
||||||
|
},
|
||||||
|
enumerable: true,
|
||||||
|
configurable: true,
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,21 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var isValid = require('./borderStyle').isValid;
|
||||||
|
module.exports.isValid = isValid;
|
||||||
|
|
||||||
|
module.exports.definition = {
|
||||||
|
set: function (v) {
|
||||||
|
if (isValid(v)) {
|
||||||
|
if (v.toLowerCase() === 'none') {
|
||||||
|
v = '';
|
||||||
|
this.removeProperty('border-bottom-width');
|
||||||
|
}
|
||||||
|
this._setProperty('border-bottom-style', v);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
get: function () {
|
||||||
|
return this.getPropertyValue('border-bottom-style');
|
||||||
|
},
|
||||||
|
enumerable: true,
|
||||||
|
configurable: true,
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,16 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var isValid = (module.exports.isValid = require('./borderWidth').isValid);
|
||||||
|
|
||||||
|
module.exports.definition = {
|
||||||
|
set: function (v) {
|
||||||
|
if (isValid(v)) {
|
||||||
|
this._setProperty('border-bottom-width', v);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
get: function () {
|
||||||
|
return this.getPropertyValue('border-bottom-width');
|
||||||
|
},
|
||||||
|
enumerable: true,
|
||||||
|
configurable: true,
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,26 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var parsers = require('../parsers');
|
||||||
|
|
||||||
|
var parse = function parse(v) {
|
||||||
|
if (
|
||||||
|
parsers.valueType(v) === parsers.TYPES.KEYWORD &&
|
||||||
|
(v.toLowerCase() === 'collapse' ||
|
||||||
|
v.toLowerCase() === 'separate' ||
|
||||||
|
v.toLowerCase() === 'inherit')
|
||||||
|
) {
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports.definition = {
|
||||||
|
set: function (v) {
|
||||||
|
this._setProperty('border-collapse', parse(v));
|
||||||
|
},
|
||||||
|
get: function () {
|
||||||
|
return this.getPropertyValue('border-collapse');
|
||||||
|
},
|
||||||
|
enumerable: true,
|
||||||
|
configurable: true,
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,30 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var parsers = require('../parsers');
|
||||||
|
var implicitSetter = require('../parsers').implicitSetter;
|
||||||
|
|
||||||
|
module.exports.isValid = function parse(v) {
|
||||||
|
if (typeof v !== 'string') {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
v === '' || v.toLowerCase() === 'transparent' || parsers.valueType(v) === parsers.TYPES.COLOR
|
||||||
|
);
|
||||||
|
};
|
||||||
|
var isValid = module.exports.isValid;
|
||||||
|
|
||||||
|
var parser = function (v) {
|
||||||
|
if (isValid(v)) {
|
||||||
|
return v.toLowerCase();
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports.definition = {
|
||||||
|
set: implicitSetter('border', 'color', isValid, parser),
|
||||||
|
get: function () {
|
||||||
|
return this.getPropertyValue('border-color');
|
||||||
|
},
|
||||||
|
enumerable: true,
|
||||||
|
configurable: true,
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,17 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var shorthandSetter = require('../parsers').shorthandSetter;
|
||||||
|
var shorthandGetter = require('../parsers').shorthandGetter;
|
||||||
|
|
||||||
|
var shorthand_for = {
|
||||||
|
'border-left-width': require('./borderLeftWidth'),
|
||||||
|
'border-left-style': require('./borderLeftStyle'),
|
||||||
|
'border-left-color': require('./borderLeftColor'),
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports.definition = {
|
||||||
|
set: shorthandSetter('border-left', shorthand_for),
|
||||||
|
get: shorthandGetter('border-left', shorthand_for),
|
||||||
|
enumerable: true,
|
||||||
|
configurable: true,
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,16 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var isValid = (module.exports.isValid = require('./borderColor').isValid);
|
||||||
|
|
||||||
|
module.exports.definition = {
|
||||||
|
set: function (v) {
|
||||||
|
if (isValid(v)) {
|
||||||
|
this._setProperty('border-left-color', v);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
get: function () {
|
||||||
|
return this.getPropertyValue('border-left-color');
|
||||||
|
},
|
||||||
|
enumerable: true,
|
||||||
|
configurable: true,
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,21 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var isValid = require('./borderStyle').isValid;
|
||||||
|
module.exports.isValid = isValid;
|
||||||
|
|
||||||
|
module.exports.definition = {
|
||||||
|
set: function (v) {
|
||||||
|
if (isValid(v)) {
|
||||||
|
if (v.toLowerCase() === 'none') {
|
||||||
|
v = '';
|
||||||
|
this.removeProperty('border-left-width');
|
||||||
|
}
|
||||||
|
this._setProperty('border-left-style', v);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
get: function () {
|
||||||
|
return this.getPropertyValue('border-left-style');
|
||||||
|
},
|
||||||
|
enumerable: true,
|
||||||
|
configurable: true,
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,16 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var isValid = (module.exports.isValid = require('./borderWidth').isValid);
|
||||||
|
|
||||||
|
module.exports.definition = {
|
||||||
|
set: function (v) {
|
||||||
|
if (isValid(v)) {
|
||||||
|
this._setProperty('border-left-width', v);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
get: function () {
|
||||||
|
return this.getPropertyValue('border-left-width');
|
||||||
|
},
|
||||||
|
enumerable: true,
|
||||||
|
configurable: true,
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,17 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var shorthandSetter = require('../parsers').shorthandSetter;
|
||||||
|
var shorthandGetter = require('../parsers').shorthandGetter;
|
||||||
|
|
||||||
|
var shorthand_for = {
|
||||||
|
'border-right-width': require('./borderRightWidth'),
|
||||||
|
'border-right-style': require('./borderRightStyle'),
|
||||||
|
'border-right-color': require('./borderRightColor'),
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports.definition = {
|
||||||
|
set: shorthandSetter('border-right', shorthand_for),
|
||||||
|
get: shorthandGetter('border-right', shorthand_for),
|
||||||
|
enumerable: true,
|
||||||
|
configurable: true,
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,16 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var isValid = (module.exports.isValid = require('./borderColor').isValid);
|
||||||
|
|
||||||
|
module.exports.definition = {
|
||||||
|
set: function (v) {
|
||||||
|
if (isValid(v)) {
|
||||||
|
this._setProperty('border-right-color', v);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
get: function () {
|
||||||
|
return this.getPropertyValue('border-right-color');
|
||||||
|
},
|
||||||
|
enumerable: true,
|
||||||
|
configurable: true,
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,21 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var isValid = require('./borderStyle').isValid;
|
||||||
|
module.exports.isValid = isValid;
|
||||||
|
|
||||||
|
module.exports.definition = {
|
||||||
|
set: function (v) {
|
||||||
|
if (isValid(v)) {
|
||||||
|
if (v.toLowerCase() === 'none') {
|
||||||
|
v = '';
|
||||||
|
this.removeProperty('border-right-width');
|
||||||
|
}
|
||||||
|
this._setProperty('border-right-style', v);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
get: function () {
|
||||||
|
return this.getPropertyValue('border-right-style');
|
||||||
|
},
|
||||||
|
enumerable: true,
|
||||||
|
configurable: true,
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,16 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var isValid = (module.exports.isValid = require('./borderWidth').isValid);
|
||||||
|
|
||||||
|
module.exports.definition = {
|
||||||
|
set: function (v) {
|
||||||
|
if (isValid(v)) {
|
||||||
|
this._setProperty('border-right-width', v);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
get: function () {
|
||||||
|
return this.getPropertyValue('border-right-width');
|
||||||
|
},
|
||||||
|
enumerable: true,
|
||||||
|
configurable: true,
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,41 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var parsers = require('../parsers');
|
||||||
|
|
||||||
|
// <length> <length>? | inherit
|
||||||
|
// if one, it applies to both horizontal and verical spacing
|
||||||
|
// if two, the first applies to the horizontal and the second applies to vertical spacing
|
||||||
|
|
||||||
|
var parse = function parse(v) {
|
||||||
|
if (v === '' || v === null) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
if (v === 0) {
|
||||||
|
return '0px';
|
||||||
|
}
|
||||||
|
if (v.toLowerCase() === 'inherit') {
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
var parts = v.split(/\s+/);
|
||||||
|
if (parts.length !== 1 && parts.length !== 2) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
parts.forEach(function (part) {
|
||||||
|
if (parsers.valueType(part) !== parsers.TYPES.LENGTH) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return v;
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports.definition = {
|
||||||
|
set: function (v) {
|
||||||
|
this._setProperty('border-spacing', parse(v));
|
||||||
|
},
|
||||||
|
get: function () {
|
||||||
|
return this.getPropertyValue('border-spacing');
|
||||||
|
},
|
||||||
|
enumerable: true,
|
||||||
|
configurable: true,
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,38 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var implicitSetter = require('../parsers').implicitSetter;
|
||||||
|
|
||||||
|
// the valid border-styles:
|
||||||
|
var styles = [
|
||||||
|
'none',
|
||||||
|
'hidden',
|
||||||
|
'dotted',
|
||||||
|
'dashed',
|
||||||
|
'solid',
|
||||||
|
'double',
|
||||||
|
'groove',
|
||||||
|
'ridge',
|
||||||
|
'inset',
|
||||||
|
'outset',
|
||||||
|
];
|
||||||
|
|
||||||
|
module.exports.isValid = function parse(v) {
|
||||||
|
return typeof v === 'string' && (v === '' || styles.indexOf(v) !== -1);
|
||||||
|
};
|
||||||
|
var isValid = module.exports.isValid;
|
||||||
|
|
||||||
|
var parser = function (v) {
|
||||||
|
if (isValid(v)) {
|
||||||
|
return v.toLowerCase();
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports.definition = {
|
||||||
|
set: implicitSetter('border', 'style', isValid, parser),
|
||||||
|
get: function () {
|
||||||
|
return this.getPropertyValue('border-style');
|
||||||
|
},
|
||||||
|
enumerable: true,
|
||||||
|
configurable: true,
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,17 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var shorthandSetter = require('../parsers').shorthandSetter;
|
||||||
|
var shorthandGetter = require('../parsers').shorthandGetter;
|
||||||
|
|
||||||
|
var shorthand_for = {
|
||||||
|
'border-top-width': require('./borderTopWidth'),
|
||||||
|
'border-top-style': require('./borderTopStyle'),
|
||||||
|
'border-top-color': require('./borderTopColor'),
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports.definition = {
|
||||||
|
set: shorthandSetter('border-top', shorthand_for),
|
||||||
|
get: shorthandGetter('border-top', shorthand_for),
|
||||||
|
enumerable: true,
|
||||||
|
configurable: true,
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,16 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var isValid = (module.exports.isValid = require('./borderColor').isValid);
|
||||||
|
|
||||||
|
module.exports.definition = {
|
||||||
|
set: function (v) {
|
||||||
|
if (isValid(v)) {
|
||||||
|
this._setProperty('border-top-color', v);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
get: function () {
|
||||||
|
return this.getPropertyValue('border-top-color');
|
||||||
|
},
|
||||||
|
enumerable: true,
|
||||||
|
configurable: true,
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,21 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var isValid = require('./borderStyle').isValid;
|
||||||
|
module.exports.isValid = isValid;
|
||||||
|
|
||||||
|
module.exports.definition = {
|
||||||
|
set: function (v) {
|
||||||
|
if (isValid(v)) {
|
||||||
|
if (v.toLowerCase() === 'none') {
|
||||||
|
v = '';
|
||||||
|
this.removeProperty('border-top-width');
|
||||||
|
}
|
||||||
|
this._setProperty('border-top-style', v);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
get: function () {
|
||||||
|
return this.getPropertyValue('border-top-style');
|
||||||
|
},
|
||||||
|
enumerable: true,
|
||||||
|
configurable: true,
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,17 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var isValid = require('./borderWidth').isValid;
|
||||||
|
module.exports.isValid = isValid;
|
||||||
|
|
||||||
|
module.exports.definition = {
|
||||||
|
set: function (v) {
|
||||||
|
if (isValid(v)) {
|
||||||
|
this._setProperty('border-top-width', v);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
get: function () {
|
||||||
|
return this.getPropertyValue('border-top-width');
|
||||||
|
},
|
||||||
|
enumerable: true,
|
||||||
|
configurable: true,
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,46 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var parsers = require('../parsers');
|
||||||
|
var implicitSetter = require('../parsers').implicitSetter;
|
||||||
|
|
||||||
|
// the valid border-widths:
|
||||||
|
var widths = ['thin', 'medium', 'thick'];
|
||||||
|
|
||||||
|
module.exports.isValid = function parse(v) {
|
||||||
|
var length = parsers.parseLength(v);
|
||||||
|
if (length !== undefined) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (typeof v !== 'string') {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (v === '') {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
v = v.toLowerCase();
|
||||||
|
if (widths.indexOf(v) === -1) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
var isValid = module.exports.isValid;
|
||||||
|
|
||||||
|
var parser = function (v) {
|
||||||
|
var length = parsers.parseLength(v);
|
||||||
|
if (length !== undefined) {
|
||||||
|
return length;
|
||||||
|
}
|
||||||
|
if (isValid(v)) {
|
||||||
|
return v.toLowerCase();
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports.definition = {
|
||||||
|
set: implicitSetter('border', 'width', isValid, parser),
|
||||||
|
get: function () {
|
||||||
|
return this.getPropertyValue('border-width');
|
||||||
|
},
|
||||||
|
enumerable: true,
|
||||||
|
configurable: true,
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,14 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var parseMeasurement = require('../parsers').parseMeasurement;
|
||||||
|
|
||||||
|
module.exports.definition = {
|
||||||
|
set: function (v) {
|
||||||
|
this._setProperty('bottom', parseMeasurement(v));
|
||||||
|
},
|
||||||
|
get: function () {
|
||||||
|
return this.getPropertyValue('bottom');
|
||||||
|
},
|
||||||
|
enumerable: true,
|
||||||
|
configurable: true,
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,16 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var parseKeyword = require('../parsers').parseKeyword;
|
||||||
|
|
||||||
|
var clear_keywords = ['none', 'left', 'right', 'both', 'inherit'];
|
||||||
|
|
||||||
|
module.exports.definition = {
|
||||||
|
set: function (v) {
|
||||||
|
this._setProperty('clear', parseKeyword(v, clear_keywords));
|
||||||
|
},
|
||||||
|
get: function () {
|
||||||
|
return this.getPropertyValue('clear');
|
||||||
|
},
|
||||||
|
enumerable: true,
|
||||||
|
configurable: true,
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,47 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var parseMeasurement = require('../parsers').parseMeasurement;
|
||||||
|
|
||||||
|
var shape_regex = /^rect\((.*)\)$/i;
|
||||||
|
|
||||||
|
var parse = function (val) {
|
||||||
|
if (val === '' || val === null) {
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
if (typeof val !== 'string') {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
val = val.toLowerCase();
|
||||||
|
if (val === 'auto' || val === 'inherit') {
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
var matches = val.match(shape_regex);
|
||||||
|
if (!matches) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
var parts = matches[1].split(/\s*,\s*/);
|
||||||
|
if (parts.length !== 4) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
var valid = parts.every(function (part, index) {
|
||||||
|
var measurement = parseMeasurement(part);
|
||||||
|
parts[index] = measurement;
|
||||||
|
return measurement !== undefined;
|
||||||
|
});
|
||||||
|
if (!valid) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
parts = parts.join(', ');
|
||||||
|
return val.replace(matches[1], parts);
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports.definition = {
|
||||||
|
set: function (v) {
|
||||||
|
this._setProperty('clip', parse(v));
|
||||||
|
},
|
||||||
|
get: function () {
|
||||||
|
return this.getPropertyValue('clip');
|
||||||
|
},
|
||||||
|
enumerable: true,
|
||||||
|
configurable: true,
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,14 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var parseColor = require('../parsers').parseColor;
|
||||||
|
|
||||||
|
module.exports.definition = {
|
||||||
|
set: function (v) {
|
||||||
|
this._setProperty('color', parseColor(v));
|
||||||
|
},
|
||||||
|
get: function () {
|
||||||
|
return this.getPropertyValue('color');
|
||||||
|
},
|
||||||
|
enumerable: true,
|
||||||
|
configurable: true,
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,12 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
module.exports.definition = {
|
||||||
|
set: function (v) {
|
||||||
|
this._setProperty('float', v);
|
||||||
|
},
|
||||||
|
get: function () {
|
||||||
|
return this.getPropertyValue('float');
|
||||||
|
},
|
||||||
|
enumerable: true,
|
||||||
|
configurable: true,
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,43 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var shorthandParser = require('../parsers').shorthandParser;
|
||||||
|
var shorthandSetter = require('../parsers').shorthandSetter;
|
||||||
|
var shorthandGetter = require('../parsers').shorthandGetter;
|
||||||
|
|
||||||
|
var shorthand_for = {
|
||||||
|
'flex-grow': require('./flexGrow'),
|
||||||
|
'flex-shrink': require('./flexShrink'),
|
||||||
|
'flex-basis': require('./flexBasis'),
|
||||||
|
};
|
||||||
|
|
||||||
|
var myShorthandSetter = shorthandSetter('flex', shorthand_for);
|
||||||
|
|
||||||
|
module.exports.isValid = function isValid(v) {
|
||||||
|
return shorthandParser(v, shorthand_for) !== undefined;
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports.definition = {
|
||||||
|
set: function (v) {
|
||||||
|
var normalizedValue = String(v).trim().toLowerCase();
|
||||||
|
|
||||||
|
if (normalizedValue === 'none') {
|
||||||
|
myShorthandSetter.call(this, '0 0 auto');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (normalizedValue === 'initial') {
|
||||||
|
myShorthandSetter.call(this, '0 1 auto');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (normalizedValue === 'auto') {
|
||||||
|
this.removeProperty('flex-grow');
|
||||||
|
this.removeProperty('flex-shrink');
|
||||||
|
this.setProperty('flex-basis', normalizedValue);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
myShorthandSetter.call(this, v);
|
||||||
|
},
|
||||||
|
get: shorthandGetter('flex', shorthand_for),
|
||||||
|
enumerable: true,
|
||||||
|
configurable: true,
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,28 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var parseMeasurement = require('../parsers').parseMeasurement;
|
||||||
|
|
||||||
|
function parse(v) {
|
||||||
|
if (String(v).toLowerCase() === 'auto') {
|
||||||
|
return 'auto';
|
||||||
|
}
|
||||||
|
if (String(v).toLowerCase() === 'inherit') {
|
||||||
|
return 'inherit';
|
||||||
|
}
|
||||||
|
return parseMeasurement(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports.isValid = function isValid(v) {
|
||||||
|
return parse(v) !== undefined;
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports.definition = {
|
||||||
|
set: function (v) {
|
||||||
|
this._setProperty('flex-basis', parse(v));
|
||||||
|
},
|
||||||
|
get: function () {
|
||||||
|
return this.getPropertyValue('flex-basis');
|
||||||
|
},
|
||||||
|
enumerable: true,
|
||||||
|
configurable: true,
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,19 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var parseNumber = require('../parsers').parseNumber;
|
||||||
|
var POSITION_AT_SHORTHAND = require('../constants').POSITION_AT_SHORTHAND;
|
||||||
|
|
||||||
|
module.exports.isValid = function isValid(v, positionAtFlexShorthand) {
|
||||||
|
return parseNumber(v) !== undefined && positionAtFlexShorthand === POSITION_AT_SHORTHAND.first;
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports.definition = {
|
||||||
|
set: function (v) {
|
||||||
|
this._setProperty('flex-grow', parseNumber(v));
|
||||||
|
},
|
||||||
|
get: function () {
|
||||||
|
return this.getPropertyValue('flex-grow');
|
||||||
|
},
|
||||||
|
enumerable: true,
|
||||||
|
configurable: true,
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,19 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var parseNumber = require('../parsers').parseNumber;
|
||||||
|
var POSITION_AT_SHORTHAND = require('../constants').POSITION_AT_SHORTHAND;
|
||||||
|
|
||||||
|
module.exports.isValid = function isValid(v, positionAtFlexShorthand) {
|
||||||
|
return parseNumber(v) !== undefined && positionAtFlexShorthand === POSITION_AT_SHORTHAND.second;
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports.definition = {
|
||||||
|
set: function (v) {
|
||||||
|
this._setProperty('flex-shrink', parseNumber(v));
|
||||||
|
},
|
||||||
|
get: function () {
|
||||||
|
return this.getPropertyValue('flex-shrink');
|
||||||
|
},
|
||||||
|
enumerable: true,
|
||||||
|
configurable: true,
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,12 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
module.exports.definition = {
|
||||||
|
set: function (v) {
|
||||||
|
this._setProperty('float', v);
|
||||||
|
},
|
||||||
|
get: function () {
|
||||||
|
return this.getPropertyValue('float');
|
||||||
|
},
|
||||||
|
enumerable: true,
|
||||||
|
configurable: true,
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,14 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var parseColor = require('../parsers').parseColor;
|
||||||
|
|
||||||
|
module.exports.definition = {
|
||||||
|
set: function (v) {
|
||||||
|
this._setProperty('flood-color', parseColor(v));
|
||||||
|
},
|
||||||
|
get: function () {
|
||||||
|
return this.getPropertyValue('flood-color');
|
||||||
|
},
|
||||||
|
enumerable: true,
|
||||||
|
configurable: true,
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,43 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var TYPES = require('../parsers').TYPES;
|
||||||
|
var valueType = require('../parsers').valueType;
|
||||||
|
var shorthandParser = require('../parsers').shorthandParser;
|
||||||
|
var shorthandSetter = require('../parsers').shorthandSetter;
|
||||||
|
var shorthandGetter = require('../parsers').shorthandGetter;
|
||||||
|
|
||||||
|
var shorthand_for = {
|
||||||
|
'font-family': require('./fontFamily'),
|
||||||
|
'font-size': require('./fontSize'),
|
||||||
|
'font-style': require('./fontStyle'),
|
||||||
|
'font-variant': require('./fontVariant'),
|
||||||
|
'font-weight': require('./fontWeight'),
|
||||||
|
'line-height': require('./lineHeight'),
|
||||||
|
};
|
||||||
|
|
||||||
|
var static_fonts = [
|
||||||
|
'caption',
|
||||||
|
'icon',
|
||||||
|
'menu',
|
||||||
|
'message-box',
|
||||||
|
'small-caption',
|
||||||
|
'status-bar',
|
||||||
|
'inherit',
|
||||||
|
];
|
||||||
|
|
||||||
|
var setter = shorthandSetter('font', shorthand_for);
|
||||||
|
|
||||||
|
module.exports.definition = {
|
||||||
|
set: function (v) {
|
||||||
|
var short = shorthandParser(v, shorthand_for);
|
||||||
|
if (short !== undefined) {
|
||||||
|
return setter.call(this, v);
|
||||||
|
}
|
||||||
|
if (valueType(v) === TYPES.KEYWORD && static_fonts.indexOf(v.toLowerCase()) !== -1) {
|
||||||
|
this._setProperty('font', v);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
get: shorthandGetter('font', shorthand_for),
|
||||||
|
enumerable: true,
|
||||||
|
configurable: true,
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,33 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var TYPES = require('../parsers').TYPES;
|
||||||
|
var valueType = require('../parsers').valueType;
|
||||||
|
|
||||||
|
var partsRegEx = /\s*,\s*/;
|
||||||
|
module.exports.isValid = function isValid(v) {
|
||||||
|
if (v === '' || v === null) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
var parts = v.split(partsRegEx);
|
||||||
|
var len = parts.length;
|
||||||
|
var i;
|
||||||
|
var type;
|
||||||
|
for (i = 0; i < len; i++) {
|
||||||
|
type = valueType(parts[i]);
|
||||||
|
if (type === TYPES.STRING || type === TYPES.KEYWORD) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports.definition = {
|
||||||
|
set: function (v) {
|
||||||
|
this._setProperty('font-family', v);
|
||||||
|
},
|
||||||
|
get: function () {
|
||||||
|
return this.getPropertyValue('font-family');
|
||||||
|
},
|
||||||
|
enumerable: true,
|
||||||
|
configurable: true,
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,38 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var TYPES = require('../parsers').TYPES;
|
||||||
|
var valueType = require('../parsers').valueType;
|
||||||
|
var parseMeasurement = require('../parsers').parseMeasurement;
|
||||||
|
|
||||||
|
var absoluteSizes = ['xx-small', 'x-small', 'small', 'medium', 'large', 'x-large', 'xx-large'];
|
||||||
|
var relativeSizes = ['larger', 'smaller'];
|
||||||
|
|
||||||
|
module.exports.isValid = function (v) {
|
||||||
|
var type = valueType(v.toLowerCase());
|
||||||
|
return (
|
||||||
|
type === TYPES.LENGTH ||
|
||||||
|
type === TYPES.PERCENT ||
|
||||||
|
(type === TYPES.KEYWORD && absoluteSizes.indexOf(v.toLowerCase()) !== -1) ||
|
||||||
|
(type === TYPES.KEYWORD && relativeSizes.indexOf(v.toLowerCase()) !== -1)
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
function parse(v) {
|
||||||
|
const valueAsString = String(v).toLowerCase();
|
||||||
|
const optionalArguments = absoluteSizes.concat(relativeSizes);
|
||||||
|
const isOptionalArgument = optionalArguments.some(
|
||||||
|
(stringValue) => stringValue.toLowerCase() === valueAsString
|
||||||
|
);
|
||||||
|
return isOptionalArgument ? valueAsString : parseMeasurement(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports.definition = {
|
||||||
|
set: function (v) {
|
||||||
|
this._setProperty('font-size', parse(v));
|
||||||
|
},
|
||||||
|
get: function () {
|
||||||
|
return this.getPropertyValue('font-size');
|
||||||
|
},
|
||||||
|
enumerable: true,
|
||||||
|
configurable: true,
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var valid_styles = ['normal', 'italic', 'oblique', 'inherit'];
|
||||||
|
|
||||||
|
module.exports.isValid = function (v) {
|
||||||
|
return valid_styles.indexOf(v.toLowerCase()) !== -1;
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports.definition = {
|
||||||
|
set: function (v) {
|
||||||
|
this._setProperty('font-style', v);
|
||||||
|
},
|
||||||
|
get: function () {
|
||||||
|
return this.getPropertyValue('font-style');
|
||||||
|
},
|
||||||
|
enumerable: true,
|
||||||
|
configurable: true,
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var valid_variants = ['normal', 'small-caps', 'inherit'];
|
||||||
|
|
||||||
|
module.exports.isValid = function isValid(v) {
|
||||||
|
return valid_variants.indexOf(v.toLowerCase()) !== -1;
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports.definition = {
|
||||||
|
set: function (v) {
|
||||||
|
this._setProperty('font-variant', v);
|
||||||
|
},
|
||||||
|
get: function () {
|
||||||
|
return this.getPropertyValue('font-variant');
|
||||||
|
},
|
||||||
|
enumerable: true,
|
||||||
|
configurable: true,
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,33 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var valid_weights = [
|
||||||
|
'normal',
|
||||||
|
'bold',
|
||||||
|
'bolder',
|
||||||
|
'lighter',
|
||||||
|
'100',
|
||||||
|
'200',
|
||||||
|
'300',
|
||||||
|
'400',
|
||||||
|
'500',
|
||||||
|
'600',
|
||||||
|
'700',
|
||||||
|
'800',
|
||||||
|
'900',
|
||||||
|
'inherit',
|
||||||
|
];
|
||||||
|
|
||||||
|
module.exports.isValid = function isValid(v) {
|
||||||
|
return valid_weights.indexOf(v.toLowerCase()) !== -1;
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports.definition = {
|
||||||
|
set: function (v) {
|
||||||
|
this._setProperty('font-weight', v);
|
||||||
|
},
|
||||||
|
get: function () {
|
||||||
|
return this.getPropertyValue('font-weight');
|
||||||
|
},
|
||||||
|
enumerable: true,
|
||||||
|
configurable: true,
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,24 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var parseMeasurement = require('../parsers').parseMeasurement;
|
||||||
|
|
||||||
|
function parse(v) {
|
||||||
|
if (String(v).toLowerCase() === 'auto') {
|
||||||
|
return 'auto';
|
||||||
|
}
|
||||||
|
if (String(v).toLowerCase() === 'inherit') {
|
||||||
|
return 'inherit';
|
||||||
|
}
|
||||||
|
return parseMeasurement(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports.definition = {
|
||||||
|
set: function (v) {
|
||||||
|
this._setProperty('height', parse(v));
|
||||||
|
},
|
||||||
|
get: function () {
|
||||||
|
return this.getPropertyValue('height');
|
||||||
|
},
|
||||||
|
enumerable: true,
|
||||||
|
configurable: true,
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,14 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var parseMeasurement = require('../parsers').parseMeasurement;
|
||||||
|
|
||||||
|
module.exports.definition = {
|
||||||
|
set: function (v) {
|
||||||
|
this._setProperty('left', parseMeasurement(v));
|
||||||
|
},
|
||||||
|
get: function () {
|
||||||
|
return this.getPropertyValue('left');
|
||||||
|
},
|
||||||
|
enumerable: true,
|
||||||
|
configurable: true,
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,14 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var parseColor = require('../parsers').parseColor;
|
||||||
|
|
||||||
|
module.exports.definition = {
|
||||||
|
set: function (v) {
|
||||||
|
this._setProperty('lighting-color', parseColor(v));
|
||||||
|
},
|
||||||
|
get: function () {
|
||||||
|
return this.getPropertyValue('lighting-color');
|
||||||
|
},
|
||||||
|
enumerable: true,
|
||||||
|
configurable: true,
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,26 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var TYPES = require('../parsers').TYPES;
|
||||||
|
var valueType = require('../parsers').valueType;
|
||||||
|
|
||||||
|
module.exports.isValid = function isValid(v) {
|
||||||
|
var type = valueType(v);
|
||||||
|
return (
|
||||||
|
(type === TYPES.KEYWORD && v.toLowerCase() === 'normal') ||
|
||||||
|
v.toLowerCase() === 'inherit' ||
|
||||||
|
type === TYPES.NUMBER ||
|
||||||
|
type === TYPES.LENGTH ||
|
||||||
|
type === TYPES.PERCENT
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports.definition = {
|
||||||
|
set: function (v) {
|
||||||
|
this._setProperty('line-height', v);
|
||||||
|
},
|
||||||
|
get: function () {
|
||||||
|
return this.getPropertyValue('line-height');
|
||||||
|
},
|
||||||
|
enumerable: true,
|
||||||
|
configurable: true,
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,72 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var parsers = require('../parsers.js');
|
||||||
|
var TYPES = parsers.TYPES;
|
||||||
|
|
||||||
|
var isValid = function (v) {
|
||||||
|
if (v.toLowerCase() === 'auto') {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
var type = parsers.valueType(v);
|
||||||
|
return (
|
||||||
|
type === TYPES.NULL_OR_EMPTY_STR ||
|
||||||
|
type === TYPES.LENGTH ||
|
||||||
|
type === TYPES.PERCENT ||
|
||||||
|
(type === TYPES.INTEGER && (v === '0' || v === 0))
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
var parser = function (v) {
|
||||||
|
var V = v.toLowerCase();
|
||||||
|
if (V === 'auto') {
|
||||||
|
return V;
|
||||||
|
}
|
||||||
|
return parsers.parseMeasurement(v);
|
||||||
|
};
|
||||||
|
|
||||||
|
var mySetter = parsers.implicitSetter('margin', '', isValid, parser);
|
||||||
|
var myGlobal = parsers.implicitSetter(
|
||||||
|
'margin',
|
||||||
|
'',
|
||||||
|
function () {
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
function (v) {
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
module.exports.definition = {
|
||||||
|
set: function (v) {
|
||||||
|
if (typeof v === 'number') {
|
||||||
|
v = String(v);
|
||||||
|
}
|
||||||
|
if (v === null) {
|
||||||
|
v = '';
|
||||||
|
}
|
||||||
|
if (typeof v !== 'string') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var V = v.toLowerCase();
|
||||||
|
switch (V) {
|
||||||
|
case 'inherit':
|
||||||
|
case 'initial':
|
||||||
|
case 'unset':
|
||||||
|
case '':
|
||||||
|
myGlobal.call(this, V);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
mySetter.call(this, v);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
get: function () {
|
||||||
|
return this.getPropertyValue('margin');
|
||||||
|
},
|
||||||
|
enumerable: true,
|
||||||
|
configurable: true,
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports.isValid = isValid;
|
||||||
|
module.exports.parser = parser;
|
||||||
|
|
@ -0,0 +1,13 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var margin = require('./margin.js');
|
||||||
|
var parsers = require('../parsers.js');
|
||||||
|
|
||||||
|
module.exports.definition = {
|
||||||
|
set: parsers.subImplicitSetter('margin', 'bottom', margin.isValid, margin.parser),
|
||||||
|
get: function () {
|
||||||
|
return this.getPropertyValue('margin-bottom');
|
||||||
|
},
|
||||||
|
enumerable: true,
|
||||||
|
configurable: true,
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,13 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var margin = require('./margin.js');
|
||||||
|
var parsers = require('../parsers.js');
|
||||||
|
|
||||||
|
module.exports.definition = {
|
||||||
|
set: parsers.subImplicitSetter('margin', 'left', margin.isValid, margin.parser),
|
||||||
|
get: function () {
|
||||||
|
return this.getPropertyValue('margin-left');
|
||||||
|
},
|
||||||
|
enumerable: true,
|
||||||
|
configurable: true,
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,13 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var margin = require('./margin.js');
|
||||||
|
var parsers = require('../parsers.js');
|
||||||
|
|
||||||
|
module.exports.definition = {
|
||||||
|
set: parsers.subImplicitSetter('margin', 'right', margin.isValid, margin.parser),
|
||||||
|
get: function () {
|
||||||
|
return this.getPropertyValue('margin-right');
|
||||||
|
},
|
||||||
|
enumerable: true,
|
||||||
|
configurable: true,
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,13 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var margin = require('./margin.js');
|
||||||
|
var parsers = require('../parsers.js');
|
||||||
|
|
||||||
|
module.exports.definition = {
|
||||||
|
set: parsers.subImplicitSetter('margin', 'top', margin.isValid, margin.parser),
|
||||||
|
get: function () {
|
||||||
|
return this.getPropertyValue('margin-top');
|
||||||
|
},
|
||||||
|
enumerable: true,
|
||||||
|
configurable: true,
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,14 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var parseNumber = require('../parsers').parseNumber;
|
||||||
|
|
||||||
|
module.exports.definition = {
|
||||||
|
set: function (v) {
|
||||||
|
this._setProperty('opacity', parseNumber(v));
|
||||||
|
},
|
||||||
|
get: function () {
|
||||||
|
return this.getPropertyValue('opacity');
|
||||||
|
},
|
||||||
|
enumerable: true,
|
||||||
|
configurable: true,
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,14 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var parseColor = require('../parsers').parseColor;
|
||||||
|
|
||||||
|
module.exports.definition = {
|
||||||
|
set: function (v) {
|
||||||
|
this._setProperty('outline-color', parseColor(v));
|
||||||
|
},
|
||||||
|
get: function () {
|
||||||
|
return this.getPropertyValue('outline-color');
|
||||||
|
},
|
||||||
|
enumerable: true,
|
||||||
|
configurable: true,
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,65 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var parsers = require('../parsers.js');
|
||||||
|
var TYPES = parsers.TYPES;
|
||||||
|
|
||||||
|
var isValid = function (v) {
|
||||||
|
var type = parsers.valueType(v);
|
||||||
|
return (
|
||||||
|
type === TYPES.NULL_OR_EMPTY_STR ||
|
||||||
|
type === TYPES.LENGTH ||
|
||||||
|
type === TYPES.PERCENT ||
|
||||||
|
(type === TYPES.INTEGER && (v === '0' || v === 0))
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
var parser = function (v) {
|
||||||
|
return parsers.parseMeasurement(v);
|
||||||
|
};
|
||||||
|
|
||||||
|
var mySetter = parsers.implicitSetter('padding', '', isValid, parser);
|
||||||
|
var myGlobal = parsers.implicitSetter(
|
||||||
|
'padding',
|
||||||
|
'',
|
||||||
|
function () {
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
function (v) {
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
module.exports.definition = {
|
||||||
|
set: function (v) {
|
||||||
|
if (typeof v === 'number') {
|
||||||
|
v = String(v);
|
||||||
|
}
|
||||||
|
if (v === null) {
|
||||||
|
v = '';
|
||||||
|
}
|
||||||
|
if (typeof v !== 'string') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var V = v.toLowerCase();
|
||||||
|
switch (V) {
|
||||||
|
case 'inherit':
|
||||||
|
case 'initial':
|
||||||
|
case 'unset':
|
||||||
|
case '':
|
||||||
|
myGlobal.call(this, V);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
mySetter.call(this, v);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
get: function () {
|
||||||
|
return this.getPropertyValue('padding');
|
||||||
|
},
|
||||||
|
enumerable: true,
|
||||||
|
configurable: true,
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports.isValid = isValid;
|
||||||
|
module.exports.parser = parser;
|
||||||
|
|
@ -0,0 +1,13 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var padding = require('./padding.js');
|
||||||
|
var parsers = require('../parsers.js');
|
||||||
|
|
||||||
|
module.exports.definition = {
|
||||||
|
set: parsers.subImplicitSetter('padding', 'bottom', padding.isValid, padding.parser),
|
||||||
|
get: function () {
|
||||||
|
return this.getPropertyValue('padding-bottom');
|
||||||
|
},
|
||||||
|
enumerable: true,
|
||||||
|
configurable: true,
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,13 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var padding = require('./padding.js');
|
||||||
|
var parsers = require('../parsers.js');
|
||||||
|
|
||||||
|
module.exports.definition = {
|
||||||
|
set: parsers.subImplicitSetter('padding', 'left', padding.isValid, padding.parser),
|
||||||
|
get: function () {
|
||||||
|
return this.getPropertyValue('padding-left');
|
||||||
|
},
|
||||||
|
enumerable: true,
|
||||||
|
configurable: true,
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,13 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var padding = require('./padding.js');
|
||||||
|
var parsers = require('../parsers.js');
|
||||||
|
|
||||||
|
module.exports.definition = {
|
||||||
|
set: parsers.subImplicitSetter('padding', 'right', padding.isValid, padding.parser),
|
||||||
|
get: function () {
|
||||||
|
return this.getPropertyValue('padding-right');
|
||||||
|
},
|
||||||
|
enumerable: true,
|
||||||
|
configurable: true,
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,13 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var padding = require('./padding.js');
|
||||||
|
var parsers = require('../parsers.js');
|
||||||
|
|
||||||
|
module.exports.definition = {
|
||||||
|
set: parsers.subImplicitSetter('padding', 'top', padding.isValid, padding.parser),
|
||||||
|
get: function () {
|
||||||
|
return this.getPropertyValue('padding-top');
|
||||||
|
},
|
||||||
|
enumerable: true,
|
||||||
|
configurable: true,
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,14 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var parseMeasurement = require('../parsers').parseMeasurement;
|
||||||
|
|
||||||
|
module.exports.definition = {
|
||||||
|
set: function (v) {
|
||||||
|
this._setProperty('right', parseMeasurement(v));
|
||||||
|
},
|
||||||
|
get: function () {
|
||||||
|
return this.getPropertyValue('right');
|
||||||
|
},
|
||||||
|
enumerable: true,
|
||||||
|
configurable: true,
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,14 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var parseColor = require('../parsers').parseColor;
|
||||||
|
|
||||||
|
module.exports.definition = {
|
||||||
|
set: function (v) {
|
||||||
|
this._setProperty('stop-color', parseColor(v));
|
||||||
|
},
|
||||||
|
get: function () {
|
||||||
|
return this.getPropertyValue('stop-color');
|
||||||
|
},
|
||||||
|
enumerable: true,
|
||||||
|
configurable: true,
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,14 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var parseColor = require('../parsers').parseColor;
|
||||||
|
|
||||||
|
module.exports.definition = {
|
||||||
|
set: function (v) {
|
||||||
|
this._setProperty('text-line-through-color', parseColor(v));
|
||||||
|
},
|
||||||
|
get: function () {
|
||||||
|
return this.getPropertyValue('text-line-through-color');
|
||||||
|
},
|
||||||
|
enumerable: true,
|
||||||
|
configurable: true,
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,14 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var parseColor = require('../parsers').parseColor;
|
||||||
|
|
||||||
|
module.exports.definition = {
|
||||||
|
set: function (v) {
|
||||||
|
this._setProperty('text-overline-color', parseColor(v));
|
||||||
|
},
|
||||||
|
get: function () {
|
||||||
|
return this.getPropertyValue('text-overline-color');
|
||||||
|
},
|
||||||
|
enumerable: true,
|
||||||
|
configurable: true,
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,14 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var parseColor = require('../parsers').parseColor;
|
||||||
|
|
||||||
|
module.exports.definition = {
|
||||||
|
set: function (v) {
|
||||||
|
this._setProperty('text-underline-color', parseColor(v));
|
||||||
|
},
|
||||||
|
get: function () {
|
||||||
|
return this.getPropertyValue('text-underline-color');
|
||||||
|
},
|
||||||
|
enumerable: true,
|
||||||
|
configurable: true,
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,14 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var parseMeasurement = require('../parsers').parseMeasurement;
|
||||||
|
|
||||||
|
module.exports.definition = {
|
||||||
|
set: function (v) {
|
||||||
|
this._setProperty('top', parseMeasurement(v));
|
||||||
|
},
|
||||||
|
get: function () {
|
||||||
|
return this.getPropertyValue('top');
|
||||||
|
},
|
||||||
|
enumerable: true,
|
||||||
|
configurable: true,
|
||||||
|
};
|
||||||
14
xhs/node_modules/cssstyle/lib/properties/webkitBorderAfterColor.js
generated
vendored
Normal file
14
xhs/node_modules/cssstyle/lib/properties/webkitBorderAfterColor.js
generated
vendored
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var parseColor = require('../parsers').parseColor;
|
||||||
|
|
||||||
|
module.exports.definition = {
|
||||||
|
set: function (v) {
|
||||||
|
this._setProperty('-webkit-border-after-color', parseColor(v));
|
||||||
|
},
|
||||||
|
get: function () {
|
||||||
|
return this.getPropertyValue('-webkit-border-after-color');
|
||||||
|
},
|
||||||
|
enumerable: true,
|
||||||
|
configurable: true,
|
||||||
|
};
|
||||||
14
xhs/node_modules/cssstyle/lib/properties/webkitBorderBeforeColor.js
generated
vendored
Normal file
14
xhs/node_modules/cssstyle/lib/properties/webkitBorderBeforeColor.js
generated
vendored
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var parseColor = require('../parsers').parseColor;
|
||||||
|
|
||||||
|
module.exports.definition = {
|
||||||
|
set: function (v) {
|
||||||
|
this._setProperty('-webkit-border-before-color', parseColor(v));
|
||||||
|
},
|
||||||
|
get: function () {
|
||||||
|
return this.getPropertyValue('-webkit-border-before-color');
|
||||||
|
},
|
||||||
|
enumerable: true,
|
||||||
|
configurable: true,
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,14 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var parseColor = require('../parsers').parseColor;
|
||||||
|
|
||||||
|
module.exports.definition = {
|
||||||
|
set: function (v) {
|
||||||
|
this._setProperty('-webkit-border-end-color', parseColor(v));
|
||||||
|
},
|
||||||
|
get: function () {
|
||||||
|
return this.getPropertyValue('-webkit-border-end-color');
|
||||||
|
},
|
||||||
|
enumerable: true,
|
||||||
|
configurable: true,
|
||||||
|
};
|
||||||
14
xhs/node_modules/cssstyle/lib/properties/webkitBorderStartColor.js
generated
vendored
Normal file
14
xhs/node_modules/cssstyle/lib/properties/webkitBorderStartColor.js
generated
vendored
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var parseColor = require('../parsers').parseColor;
|
||||||
|
|
||||||
|
module.exports.definition = {
|
||||||
|
set: function (v) {
|
||||||
|
this._setProperty('-webkit-border-start-color', parseColor(v));
|
||||||
|
},
|
||||||
|
get: function () {
|
||||||
|
return this.getPropertyValue('-webkit-border-start-color');
|
||||||
|
},
|
||||||
|
enumerable: true,
|
||||||
|
configurable: true,
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,14 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var parseColor = require('../parsers').parseColor;
|
||||||
|
|
||||||
|
module.exports.definition = {
|
||||||
|
set: function (v) {
|
||||||
|
this._setProperty('-webkit-column-rule-color', parseColor(v));
|
||||||
|
},
|
||||||
|
get: function () {
|
||||||
|
return this.getPropertyValue('-webkit-column-rule-color');
|
||||||
|
},
|
||||||
|
enumerable: true,
|
||||||
|
configurable: true,
|
||||||
|
};
|
||||||
14
xhs/node_modules/cssstyle/lib/properties/webkitMatchNearestMailBlockquoteColor.js
generated
vendored
Normal file
14
xhs/node_modules/cssstyle/lib/properties/webkitMatchNearestMailBlockquoteColor.js
generated
vendored
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var parseColor = require('../parsers').parseColor;
|
||||||
|
|
||||||
|
module.exports.definition = {
|
||||||
|
set: function (v) {
|
||||||
|
this._setProperty('-webkit-match-nearest-mail-blockquote-color', parseColor(v));
|
||||||
|
},
|
||||||
|
get: function () {
|
||||||
|
return this.getPropertyValue('-webkit-match-nearest-mail-blockquote-color');
|
||||||
|
},
|
||||||
|
enumerable: true,
|
||||||
|
configurable: true,
|
||||||
|
};
|
||||||
14
xhs/node_modules/cssstyle/lib/properties/webkitTapHighlightColor.js
generated
vendored
Normal file
14
xhs/node_modules/cssstyle/lib/properties/webkitTapHighlightColor.js
generated
vendored
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var parseColor = require('../parsers').parseColor;
|
||||||
|
|
||||||
|
module.exports.definition = {
|
||||||
|
set: function (v) {
|
||||||
|
this._setProperty('-webkit-tap-highlight-color', parseColor(v));
|
||||||
|
},
|
||||||
|
get: function () {
|
||||||
|
return this.getPropertyValue('-webkit-tap-highlight-color');
|
||||||
|
},
|
||||||
|
enumerable: true,
|
||||||
|
configurable: true,
|
||||||
|
};
|
||||||
14
xhs/node_modules/cssstyle/lib/properties/webkitTextEmphasisColor.js
generated
vendored
Normal file
14
xhs/node_modules/cssstyle/lib/properties/webkitTextEmphasisColor.js
generated
vendored
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var parseColor = require('../parsers').parseColor;
|
||||||
|
|
||||||
|
module.exports.definition = {
|
||||||
|
set: function (v) {
|
||||||
|
this._setProperty('-webkit-text-emphasis-color', parseColor(v));
|
||||||
|
},
|
||||||
|
get: function () {
|
||||||
|
return this.getPropertyValue('-webkit-text-emphasis-color');
|
||||||
|
},
|
||||||
|
enumerable: true,
|
||||||
|
configurable: true,
|
||||||
|
};
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue