mirror of
https://github.com/flynx/object.js.git
synced 2025-10-29 18:40:08 +00:00
split out docs to doc.js...
Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
parent
1f23c61fd5
commit
5aed294aa6
31
README.md
31
README.md
@ -151,7 +151,6 @@ class B extends A {
|
|||||||
- [`mixins(..)` / `Mixin.mixins(..)`](#mixins--mixinmixins)
|
- [`mixins(..)` / `Mixin.mixins(..)`](#mixins--mixinmixins)
|
||||||
- [`hasMixin(..)` / `Mixin.hasMixin(..)`](#hasmixin--mixinhasmixin)
|
- [`hasMixin(..)` / `Mixin.hasMixin(..)`](#hasmixin--mixinhasmixin)
|
||||||
- [Utilities](#utilities)
|
- [Utilities](#utilities)
|
||||||
- [`normalizeIndent(..)` / `normalizeTextIndent(..)` / `doc` / `text`](#normalizeindent--normalizetextindent--doc--text)
|
|
||||||
- [`deepKeys(..)` / `Constructor.deepKeys(..)`](#deepkeys--constructordeepkeys)
|
- [`deepKeys(..)` / `Constructor.deepKeys(..)`](#deepkeys--constructordeepkeys)
|
||||||
- [`match(..)` / `Constructor.match(..)`](#match--constructormatch)
|
- [`match(..)` / `Constructor.match(..)`](#match--constructormatch)
|
||||||
- [`matchPartial(..)` / `Constructor.matchPartial(..)`](#matchpartial--constructormatchpartial)
|
- [`matchPartial(..)` / `Constructor.matchPartial(..)`](#matchpartial--constructormatchpartial)
|
||||||
@ -1022,36 +1021,6 @@ hasMixin(<base>, <mixin>)
|
|||||||
|
|
||||||
## Utilities
|
## Utilities
|
||||||
|
|
||||||
### `normalizeIndent(..)` / `normalizeTextIndent(..)` / `doc` / `text`
|
|
||||||
|
|
||||||
Align _code_ to shortest leading white-space
|
|
||||||
```
|
|
||||||
normalizeIndent(<text>)
|
|
||||||
normalizeIndent(<text>, <tab-size>)
|
|
||||||
normalizeIndent(<text>, <tab-size>, <leading-tabs>)
|
|
||||||
-> <text>
|
|
||||||
```
|
|
||||||
|
|
||||||
This is used to format `.toString(..)` return values for nested functions
|
|
||||||
to make source printing in console more pleasant to read.
|
|
||||||
|
|
||||||
`tab_size` defaults to `object.TAB_SIZE`
|
|
||||||
|
|
||||||
`leading_tabs` defaults to `object.LEADING_TABS`
|
|
||||||
|
|
||||||
|
|
||||||
A shorthand to `normalizeIndent(..)` optimized for text rather than code
|
|
||||||
```
|
|
||||||
normalizeTextIndent(..)
|
|
||||||
-> <text>
|
|
||||||
```
|
|
||||||
|
|
||||||
This ignores `object.LEADING_TABS` and `leading_tabs` is 0 by default.
|
|
||||||
|
|
||||||
|
|
||||||
`doc` and `text` are template string versions of `normalizeIndent(..)` and `normalizeTextIndent(..)` respectively.
|
|
||||||
|
|
||||||
|
|
||||||
### `deepKeys(..)` / `Constructor.deepKeys(..)`
|
### `deepKeys(..)` / `Constructor.deepKeys(..)`
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|||||||
144
object.js
144
object.js
@ -21,6 +21,13 @@
|
|||||||
(function(require){ var module={} // make module AMD/node compatible...
|
(function(require){ var module={} // make module AMD/node compatible...
|
||||||
/*********************************************************************/
|
/*********************************************************************/
|
||||||
|
|
||||||
|
var doc = require('ig-doc')
|
||||||
|
|
||||||
|
module.doc = doc.doc
|
||||||
|
module.text = doc.text
|
||||||
|
module.normalizeIndent = doc.normalizeIndent
|
||||||
|
module.normalizeTextIndent = doc.normalizeTextIndent
|
||||||
|
|
||||||
var STOP =
|
var STOP =
|
||||||
module.STOP =
|
module.STOP =
|
||||||
require('ig-stoppable').STOP
|
require('ig-stoppable').STOP
|
||||||
@ -66,129 +73,6 @@ function(func){
|
|||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
|
||||||
module.TAB_SIZE = 4
|
|
||||||
|
|
||||||
module.LEADING_TABS = 1
|
|
||||||
|
|
||||||
|
|
||||||
// Normalize code indent...
|
|
||||||
//
|
|
||||||
// normalizeIndent(text)
|
|
||||||
// -> text
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// This will remove common indent from each line of text, this is useful
|
|
||||||
// for printing function code of functions that were defined at deep
|
|
||||||
// levels of indent.
|
|
||||||
//
|
|
||||||
// This will ignore the indent of the first line.
|
|
||||||
//
|
|
||||||
// If the last line is indented higher or equal to the rest of the text
|
|
||||||
// we will use leading_tabs (defaults to LEADING_TABS) to indent the
|
|
||||||
// rest of the text.
|
|
||||||
// This will indent the following styles correctnly:
|
|
||||||
//
|
|
||||||
// |function(a, b){ |function(a, b){
|
|
||||||
// | return a + b } | return a + b
|
|
||||||
// | |}
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// NOTE: this will trim out both leading and trailing white-space.
|
|
||||||
// NOTE: this is generally code-agnostic with one sigificant
|
|
||||||
// exception -- normalizeIndent(..) will break code written
|
|
||||||
// in Whitespace.
|
|
||||||
//
|
|
||||||
// XXX BUG?
|
|
||||||
// `a `a `a
|
|
||||||
// | b -> |b expected? | b
|
|
||||||
// | c` | c` | c`
|
|
||||||
// while:
|
|
||||||
// `a `a
|
|
||||||
// | b -> | b as expected.
|
|
||||||
// | c` | c`
|
|
||||||
// this leads to functions like the following to get messed up:
|
|
||||||
// |function(a){
|
|
||||||
// | return a
|
|
||||||
// | || 'moo' }
|
|
||||||
//
|
|
||||||
// XXX is this the right place for this???
|
|
||||||
// ...when moving take care that ImageGrid's core.doc uses this...
|
|
||||||
var normalizeIndent =
|
|
||||||
module.normalizeIndent =
|
|
||||||
function(text, {tab_size=module.TAB_SIZE, leading_tabs=module.LEADING_TABS, pad_tabs=0}={}){
|
|
||||||
leading_tabs *= tab_size
|
|
||||||
var padding = ' '.repeat(pad_tabs*tab_size)
|
|
||||||
// prepare text...
|
|
||||||
var tab = ' '.repeat(tab_size || 0)
|
|
||||||
text = tab != '' ?
|
|
||||||
text.replace(/\t/g, tab)
|
|
||||||
: text
|
|
||||||
// trim the tail and remove leading blank lines...
|
|
||||||
var lines = text.trimEnd().split(/\n/)
|
|
||||||
while(lines.length > 0
|
|
||||||
&& lines[0].trim() == ''){
|
|
||||||
// XXX we have two options here:
|
|
||||||
// - indent everyline including the first non-blank
|
|
||||||
// - do not indent anything (current)
|
|
||||||
// ...not sure which is best...
|
|
||||||
leading_tabs = 0
|
|
||||||
lines.shift() }
|
|
||||||
// count common indent...
|
|
||||||
var l = lines
|
|
||||||
.reduce(function(l, e, i){
|
|
||||||
var indent = e.length - e.trimLeft().length
|
|
||||||
return e.trim().length == 0
|
|
||||||
// ignore 0 indent of first line...
|
|
||||||
|| (i == 0 && indent == 0) ?
|
|
||||||
l
|
|
||||||
// last line...
|
|
||||||
: i == lines.length-1
|
|
||||||
&& indent >= l ?
|
|
||||||
// XXX feels a bit overcomplicated...
|
|
||||||
(l < 0 ?
|
|
||||||
// last of two with 0 indent on first -> indent...
|
|
||||||
Math.max(indent - leading_tabs, 0)
|
|
||||||
// ignore leading_tabs if lower indent...
|
|
||||||
: Math.min(l, Math.max(indent - leading_tabs, 0)))
|
|
||||||
// initial state...
|
|
||||||
: l < 0 ?
|
|
||||||
indent
|
|
||||||
// min...
|
|
||||||
: Math.min(l, indent) }, -1) || 0
|
|
||||||
// normalize...
|
|
||||||
return padding
|
|
||||||
+lines
|
|
||||||
.map(function(line, i){
|
|
||||||
return i == 0 ?
|
|
||||||
line
|
|
||||||
: line.slice(l) })
|
|
||||||
.join('\n'+ padding)
|
|
||||||
.trim() }
|
|
||||||
|
|
||||||
|
|
||||||
// shorthand more suted for text...
|
|
||||||
var normalizeTextIndent =
|
|
||||||
module.normalizeTextIndent =
|
|
||||||
function(text, opts={leading_tabs: 0}){
|
|
||||||
return module.normalizeIndent(text, opts) }
|
|
||||||
|
|
||||||
|
|
||||||
// template string tag versions of the above...
|
|
||||||
var doc =
|
|
||||||
module.doc =
|
|
||||||
function(strings, ...values){
|
|
||||||
return normalizeIndent(strings
|
|
||||||
.map(function(s, i){ return s + (values[i] || '') })
|
|
||||||
.join('')) }
|
|
||||||
|
|
||||||
var text =
|
|
||||||
module.text =
|
|
||||||
function(strings, ...values){
|
|
||||||
return normalizeTextIndent(strings
|
|
||||||
.map(function(s, i){ return s + (values[i] || '') })
|
|
||||||
.join('')) }
|
|
||||||
|
|
||||||
|
|
||||||
// Get keys from prototype chain...
|
// Get keys from prototype chain...
|
||||||
//
|
//
|
||||||
// deepKeys(obj[, all])
|
// deepKeys(obj[, all])
|
||||||
@ -333,12 +217,15 @@ function(obj){
|
|||||||
// NOTE: we just created func(..) so no need to sanitize it, the
|
// NOTE: we just created func(..) so no need to sanitize it, the
|
||||||
// only potential vector of atack (AFAIK) here is name and
|
// only potential vector of atack (AFAIK) here is name and
|
||||||
// that is checked above...
|
// that is checked above...
|
||||||
func.name = name
|
Object.defineProperty(func, 'name', {value: name})
|
||||||
|
/* XXX NAME...
|
||||||
|
//func.name = name
|
||||||
func.name != name
|
func.name != name
|
||||||
&& (func = eval('('+
|
&& (func = eval('('+
|
||||||
func
|
func
|
||||||
.toString()
|
.toString()
|
||||||
.replace(/function\(/, `function ${name}(`) +')'))
|
.replace(/function\(/, `function ${name}(`) +')'))
|
||||||
|
//*/
|
||||||
func.__proto__ = obj
|
func.__proto__ = obj
|
||||||
__toStringProxy(func)
|
__toStringProxy(func)
|
||||||
return func }
|
return func }
|
||||||
@ -663,7 +550,7 @@ function(func){
|
|||||||
: '__call__' in this ?
|
: '__call__' in this ?
|
||||||
this.__call__
|
this.__call__
|
||||||
: this.__proto__)
|
: this.__proto__)
|
||||||
return module.normalizeIndent(f.toString(...args)) },
|
return doc.normalizeIndent(f.toString(...args)) },
|
||||||
enumerable: false,
|
enumerable: false,
|
||||||
})
|
})
|
||||||
return func }
|
return func }
|
||||||
@ -1035,7 +922,9 @@ function Constructor(name, a, b, c){
|
|||||||
// Object.defineProperty(_constructor, 'name', { value: name })
|
// Object.defineProperty(_constructor, 'name', { value: name })
|
||||||
// because this does not affect the name displayed by the Chrome
|
// because this does not affect the name displayed by the Chrome
|
||||||
// DevTools. FF does not seem to care about either version of code...
|
// DevTools. FF does not seem to care about either version of code...
|
||||||
_constructor.name = name
|
Object.defineProperty(_constructor, 'name', {value: name})
|
||||||
|
/* XXX NAME...
|
||||||
|
//_constructor.name = name
|
||||||
// just in case the browser/node refuses to change the name, we'll make
|
// just in case the browser/node refuses to change the name, we'll make
|
||||||
// them a different offer ;)
|
// them a different offer ;)
|
||||||
// NOTE: it is not possible to abstract this eval(..) into something
|
// NOTE: it is not possible to abstract this eval(..) into something
|
||||||
@ -1048,6 +937,7 @@ function Constructor(name, a, b, c){
|
|||||||
_constructor
|
_constructor
|
||||||
.toString()
|
.toString()
|
||||||
.replace(/Constructor/g, name) +')'))
|
.replace(/Constructor/g, name) +')'))
|
||||||
|
//*/
|
||||||
// set .toString(..)...
|
// set .toString(..)...
|
||||||
// NOTE: this test is here to enable mixinFlat(..) to overwrite
|
// NOTE: this test is here to enable mixinFlat(..) to overwrite
|
||||||
// .toString(..) below...
|
// .toString(..) below...
|
||||||
@ -1069,7 +959,7 @@ function Constructor(name, a, b, c){
|
|||||||
.toString()
|
.toString()
|
||||||
.replace(/[^{]*{/, '{')
|
.replace(/[^{]*{/, '{')
|
||||||
: '{ .. }'
|
: '{ .. }'
|
||||||
return `${this.name}(${args})${module.normalizeIndent(code)}` },
|
return `${this.name}(${args})${doc.normalizeIndent(code)}` },
|
||||||
enumerable: false,
|
enumerable: false,
|
||||||
})
|
})
|
||||||
// set generic raw instance constructor...
|
// set generic raw instance constructor...
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "ig-object",
|
"name": "ig-object",
|
||||||
"version": "6.0.1",
|
"version": "6.1.1",
|
||||||
"description": "",
|
"description": "",
|
||||||
"main": "object.js",
|
"main": "object.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
@ -30,6 +30,7 @@
|
|||||||
"ig-test": "^1.4.8"
|
"ig-test": "^1.4.8"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"ig-doc": "*",
|
||||||
"ig-stoppable": "^2.0.0"
|
"ig-stoppable": "^2.0.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
8
test.js
8
test.js
@ -26,6 +26,8 @@ var colors = require('colors')
|
|||||||
|
|
||||||
var test = require('ig-test')
|
var test = require('ig-test')
|
||||||
|
|
||||||
|
var doc = require('ig-doc')
|
||||||
|
|
||||||
var object = require('./object')
|
var object = require('./object')
|
||||||
|
|
||||||
|
|
||||||
@ -863,10 +865,10 @@ var cases = test.Cases({
|
|||||||
|
|
||||||
// .toString(..)
|
// .toString(..)
|
||||||
assert(
|
assert(
|
||||||
callable_b.toString() == object.normalizeIndent(callable_b.__call__.toString()),
|
callable_b.toString() == doc.normalizeIndent(callable_b.__call__.toString()),
|
||||||
'toString(..) proxy to .__call__(..)')
|
'toString(..) proxy to .__call__(..)')
|
||||||
assert(
|
assert(
|
||||||
callable_b.toString() != object.normalizeIndent(callable_b.__proto__.toString()),
|
callable_b.toString() != doc.normalizeIndent(callable_b.__proto__.toString()),
|
||||||
'toString(..) proxy not to .__proto__.toString(..)')
|
'toString(..) proxy not to .__proto__.toString(..)')
|
||||||
assert(
|
assert(
|
||||||
callable_c.toString() == callable_c.__proto__.toString(),
|
callable_c.toString() == callable_c.__proto__.toString(),
|
||||||
@ -874,7 +876,7 @@ var cases = test.Cases({
|
|||||||
|
|
||||||
// create(..)...
|
// create(..)...
|
||||||
assert(
|
assert(
|
||||||
object.create(func).toString() == object.normalizeIndent(func.toString()),
|
object.create(func).toString() == doc.normalizeIndent(func.toString()),
|
||||||
'create(..): function .toString() proxy (builtin).')
|
'create(..): function .toString() proxy (builtin).')
|
||||||
assert(
|
assert(
|
||||||
object.create(func_w_tostring).toString() == func_w_tostring.toString(),
|
object.create(func_w_tostring).toString() == func_w_tostring.toString(),
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user