Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
E
ecommerce-ui
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
ecommerce-ui
Commits
5717cd1d
Commit
5717cd1d
authored
Jul 24, 2013
by
Sven Franck
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
updated to latest JIO, fixed AMD check in complex_queries.js so does not break with require
parent
7a6598b6
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
724 additions
and
533 deletions
+724
-533
js/libs/jio/complex_queries.js
js/libs/jio/complex_queries.js
+680
-495
js/libs/jio/indexstorage.js
js/libs/jio/indexstorage.js
+3
-3
js/libs/jio/jio.js
js/libs/jio/jio.js
+2
-2
js/libs/jio/localstorage.js
js/libs/jio/localstorage.js
+39
-33
No files found.
js/libs/jio/complex_queries.js
View file @
5717cd1d
...
...
@@ -28,6 +28,12 @@ var complex_queries;
"
value
"
:
value
});
}
/**
* Parse a text request to a json query object tree
*
* @param {String} string The string to parse
* @return {Object} The json query tree
*/
function
parseStringToObject
(
string
)
{
/*
...
...
@@ -714,181 +720,337 @@ if ((error_count = __NODEJS_parse(string, error_offsets, error_lookaheads)) > 0)
return
result
;
}
// parseStringToObject
_export
(
'
parseStringToObject
'
,
parseStringToObject
);
/*jslint indent: 2, maxlen: 80, sloppy: true, nomen: true */
/*global _export: true */
/**
* Create a class, manage inheritance, static methods,
* protected attributes and can hide methods or/and secure methods
* Escapes regexp special chars from a string.
*
* @param {Class} Class Classes to inherit from (0..n). The last class
* parameter will inherit from the previous one, and so on
* @param {Object} option Class option (0..n)
* @param {Boolean} [option.secure_methods=false] Make methods not configurable
* and not writable
* @param {Boolean} [option.hide_methods=false] Make methods not enumerable
* @param {Boolean} [option.secure_static_methods=true] Make static methods not
* configurable and not
* writable
* @param {Boolean} [option.hide_static_methods=false] Make static methods not
* enumerable
* @param {Object} [option.static_methods={}] Object of static methods
* @param {Function} constructor The new class constructor
* @return {Class} The new class
* @param {String} string The string to escape
* @return {String} The escaped string
*/
function
newClass
()
{
var
j
,
k
,
constructors
=
[],
option
,
new_class
;
for
(
j
=
0
;
j
<
arguments
.
length
;
j
+=
1
)
{
if
(
typeof
arguments
[
j
]
===
"
function
"
)
{
constructors
.
push
(
arguments
[
j
]);
}
else
if
(
typeof
arguments
[
j
]
===
"
object
"
)
{
option
=
option
||
{};
for
(
k
in
arguments
[
j
])
{
if
(
arguments
[
j
].
hasOwnProperty
(
k
))
{
option
[
k
]
=
arguments
[
j
][
k
];
}
}
function
stringEscapeRegexpCharacters
(
string
)
{
if
(
typeof
string
===
"
string
"
)
{
return
string
.
replace
(
/
([\\\.\$\[\]\(\)\{\}\^\?\*\+\-])
/g
,
"
\\
$1
"
);
}
throw
new
TypeError
(
"
complex_queries.stringEscapeRegexpCharacters():
"
+
"
Argument no 1 is not of type 'string'
"
);
}
_export
(
"
stringEscapeRegexpCharacters
"
,
stringEscapeRegexpCharacters
);
/**
* Convert metadata values to array of strings. ex:
*
* "a" -> ["a"],
* {"content": "a"} -> ["a"]
*
* @param {Any} value The metadata value
* @return {Array} The value in string array format
*/
function
metadataValueToStringArray
(
value
)
{
var
i
,
new_value
=
[];
if
(
value
===
undefined
)
{
return
undefined
;
}
if
(
!
Array
.
isArray
(
value
))
{
value
=
[
value
];
}
for
(
i
=
0
;
i
<
value
.
length
;
i
+=
1
)
{
if
(
typeof
value
[
i
]
===
'
object
'
)
{
new_value
[
i
]
=
value
[
i
].
content
;
}
else
{
new_value
[
i
]
=
value
[
i
];
}
}
return
new_value
;
}
function
postObjectCreation
(
that
)
{
// modify the object according to 'option'
var
key
;
if
(
option
)
{
for
(
key
in
that
)
{
if
(
that
.
hasOwnProperty
(
key
))
{
if
(
typeof
that
[
key
]
===
"
function
"
)
{
Object
.
defineProperty
(
that
,
key
,
{
"
configurable
"
:
option
.
secure_methods
?
false
:
true
,
"
enumerable
"
:
option
.
hide_methods
?
false
:
true
,
"
writable
"
:
option
.
secure_methods
?
false
:
true
,
"
value
"
:
that
[
key
]
});
}
/**
* A sort function to sort items by key
*
* @param {String} key The key to sort on
* @param {String} [way="ascending"] 'ascending' or 'descending'
* @return {Function} The sort function
*/
function
sortFunction
(
key
,
way
)
{
if
(
way
===
'
descending
'
)
{
return
function
(
a
,
b
)
{
// this comparison is 5 times faster than json comparison
var
i
,
l
;
a
=
metadataValueToStringArray
(
a
[
key
])
||
[];
b
=
metadataValueToStringArray
(
b
[
key
])
||
[];
l
=
a
.
length
>
b
.
length
?
a
.
length
:
b
.
length
;
for
(
i
=
0
;
i
<
l
;
i
+=
1
)
{
if
(
a
[
i
]
===
undefined
)
{
return
1
;
}
if
(
b
[
i
]
===
undefined
)
{
return
-
1
;
}
if
(
a
[
i
]
>
b
[
i
])
{
return
-
1
;
}
if
(
a
[
i
]
<
b
[
i
])
{
return
1
;
}
}
}
return
0
;
};
}
function
postClassCreation
(
that
)
{
// modify the object according to 'option'
var
key
;
if
(
option
)
{
for
(
key
in
that
)
{
if
(
that
.
hasOwnProperty
(
key
))
{
if
(
typeof
that
[
key
]
===
"
function
"
)
{
Object
.
defineProperty
(
that
,
key
,
{
"
configurable
"
:
option
.
secure_static_methods
===
false
?
true
:
false
,
"
enumerable
"
:
option
.
hide_static_methods
?
false
:
true
,
"
writable
"
:
option
.
secure_static_methods
===
false
?
true
:
false
,
"
value
"
:
that
[
key
]
});
}
if
(
way
===
'
ascending
'
)
{
return
function
(
a
,
b
)
{
// this comparison is 5 times faster than json comparison
var
i
,
l
;
a
=
metadataValueToStringArray
(
a
[
key
])
||
[];
b
=
metadataValueToStringArray
(
b
[
key
])
||
[];
l
=
a
.
length
>
b
.
length
?
a
.
length
:
b
.
length
;
for
(
i
=
0
;
i
<
l
;
i
+=
1
)
{
if
(
a
[
i
]
===
undefined
)
{
return
-
1
;
}
if
(
b
[
i
]
===
undefined
)
{
return
1
;
}
if
(
a
[
i
]
>
b
[
i
])
{
return
1
;
}
if
(
a
[
i
]
<
b
[
i
])
{
return
-
1
;
}
}
return
0
;
};
}
throw
new
TypeError
(
"
complex_queries.sortFunction():
"
+
"
Argument 2 must be 'ascending' or 'descending'
"
);
}
/**
* Clones all native object in deep. Managed types: Object, Array, String,
* Number, Boolean, null.
*
* @param {A} object The object to clone
* @return {A} The cloned object
*/
function
deepClone
(
object
)
{
var
i
,
cloned
;
if
(
Array
.
isArray
(
object
))
{
cloned
=
[];
for
(
i
=
0
;
i
<
object
.
length
;
i
+=
1
)
{
cloned
[
i
]
=
deepClone
(
object
[
i
]);
}
return
cloned
;
}
if
(
typeof
object
===
"
object
"
)
{
cloned
=
{};
for
(
i
in
object
)
{
if
(
object
.
hasOwnProperty
(
i
))
{
cloned
[
i
]
=
deepClone
(
object
[
i
]);
}
}
return
cloned
;
}
return
object
;
}
new_class
=
function
(
spec
,
my
)
{
var
i
;
spec
=
spec
||
{};
my
=
my
||
{};
// don't use forEach !
for
(
i
=
0
;
i
<
constructors
.
length
;
i
+=
1
)
{
constructors
[
i
].
apply
(
this
,
[
spec
,
my
]);
/**
* Inherits the prototype methods from one constructor into another. The
* prototype of `constructor` will be set to a new object created from
* `superConstructor`.
*
* @param {Function} constructor The constructor which inherits the super one
* @param {Function} superConstructor The super constructor
*/
function
inherits
(
constructor
,
superConstructor
)
{
constructor
.
super_
=
superConstructor
;
constructor
.
prototype
=
Object
.
create
(
superConstructor
.
prototype
,
{
"
constructor
"
:
{
"
configurable
"
:
true
,
"
enumerable
"
:
false
,
"
writable
"
:
true
,
"
value
"
:
constructor
}
postObjectCreation
(
this
);
return
this
;
};
option
=
option
||
{};
option
.
static_methods
=
option
.
static_methods
||
{};
for
(
j
in
option
.
static_methods
)
{
if
(
option
.
static_methods
.
hasOwnProperty
(
j
))
{
new_class
[
j
]
=
option
.
static_methods
[
j
];
});
}
/**
* Does nothing
*/
function
emptyFunction
()
{}
/**
* Filter a list of items, modifying them to select only wanted keys. If
* `clone` is true, then the method will act on a cloned list.
*
* @param {Array} select_option Key list to keep
* @param {Array} list The item list to filter
* @param {Boolean} [clone=false] If true, modifies a clone of the list
* @return {Array} The filtered list
*/
function
select
(
select_option
,
list
,
clone
)
{
var
i
,
j
,
new_item
;
if
(
!
Array
.
isArray
(
select_option
))
{
throw
new
TypeError
(
"
complex_queries.select():
"
+
"
Argument 1 is not of type Array
"
);
}
if
(
!
Array
.
isArray
(
list
))
{
throw
new
TypeError
(
"
complex_queries.select():
"
+
"
Argument 2 is not of type Array
"
);
}
if
(
clone
===
true
)
{
list
=
deepClone
(
list
);
}
for
(
i
=
0
;
i
<
list
.
length
;
i
+=
1
)
{
new_item
=
{};
for
(
j
=
0
;
j
<
select_option
.
length
;
j
+=
1
)
{
new_item
[
select_option
[
j
]]
=
list
[
i
][
select_option
[
j
]];
}
for
(
j
in
new_item
)
{
if
(
new_item
.
hasOwnProperty
(
j
))
{
list
[
i
]
=
new_item
;
break
;
}
}
}
postClassCreation
(
new_class
);
return
new_class
;
return
list
;
}
_export
(
'
select
'
,
select
);
/**
* Escapes regexp special chars from a string.
* Sort a list of items, according to keys and directions. If `clone` is true,
* then the method will act on a cloned list.
*
* @param {String} string The string to escape
* @return {String} The escaped string
* @param {Array} sort_on_option List of couples [key, direction]
* @param {Array} list The item list to sort
* @param {Boolean} [clone=false] If true, modifies a clone of the list
* @return {Array} The filtered list
*/
function
stringEscapeRegexpCharacters
(
string
)
{
if
(
typeof
string
===
"
string
"
)
{
return
string
.
replace
(
/
([\\\.\$\[\]\(\)\{\}\^\?\*\+\-])
/g
,
"
\\
$1
"
);
function
sortOn
(
sort_on_option
,
list
,
clone
)
{
var
sort_index
;
if
(
!
Array
.
isArray
(
sort_on_option
))
{
throw
new
TypeError
(
"
complex_queries.sortOn():
"
+
"
Argument 1 is not of type 'array'
"
);
}
if
(
clone
)
{
list
=
deepClone
(
list
);
}
for
(
sort_index
=
sort_on_option
.
length
-
1
;
sort_index
>=
0
;
sort_index
-=
1
)
{
list
.
sort
(
sortFunction
(
sort_on_option
[
sort_index
][
0
],
sort_on_option
[
sort_index
][
1
]
));
}
return
list
;
}
_export
(
"
stringEscapeRegexpCharacters
"
,
stringEscapeRegexpCharacters
);
_export
(
'
sortOn
'
,
sortOn
);
/**
* A sort function to sort items by key
* Limit a list of items, according to index and length. If `clone` is true,
* then the method will act on a cloned list.
*
* @param {String} key The key to sort on
* @param {String} [way="ascending"] 'ascending' or 'descending'
* @return {Function} The sort function
* @param {Array} limit_option A couple [from, length]
* @param {Array} list The item list to limit
* @param {Boolean} [clone=false] If true, modifies a clone of the list
* @return {Array} The filtered list
*/
function
sortFunction
(
key
,
way
)
{
if
(
way
===
'
descending
'
)
{
return
function
(
a
,
b
)
{
return
a
[
key
]
<
b
[
key
]
?
1
:
a
[
key
]
>
b
[
key
]
?
-
1
:
0
;
};
function
limit
(
limit_option
,
list
,
clone
)
{
if
(
!
Array
.
isArray
(
limit_option
))
{
throw
new
TypeError
(
"
complex_queries.limit():
"
+
"
Argument 1 is not of type 'array'
"
);
}
return
function
(
a
,
b
)
{
return
a
[
key
]
>
b
[
key
]
?
1
:
a
[
key
]
<
b
[
key
]
?
-
1
:
0
;
};
if
(
!
Array
.
isArray
(
list
))
{
throw
new
TypeError
(
"
complex_queries.limit():
"
+
"
Argument 2 is not of type 'array'
"
);
}
if
(
clone
)
{
list
=
deepClone
(
list
);
}
list
.
splice
(
0
,
limit_option
[
0
]);
if
(
limit_option
[
1
])
{
list
.
splice
(
limit_option
[
1
]);
}
return
list
;
}
_export
(
'
limit
'
,
limit
);
/**
* Convert a search text to a regexp.
*
* @param {String} string The string to convert
* @param {String} [wildcard_character=undefined] The wildcard chararter
* @return {RegExp} The search text regexp
*/
function
convertStringToRegExp
(
string
,
wildcard_character
)
{
if
(
typeof
string
!==
'
string
'
)
{
throw
new
TypeError
(
"
complex_queries.convertStringToRegExp():
"
+
"
Argument 1 is not of type 'string'
"
);
}
if
(
wildcard_character
===
undefined
||
wildcard_character
===
null
||
wildcard_character
===
''
)
{
return
new
RegExp
(
"
^
"
+
stringEscapeRegexpCharacters
(
string
)
+
"
$
"
);
}
if
(
typeof
wildcard_character
!==
'
string
'
||
wildcard_character
.
length
>
1
)
{
throw
new
TypeError
(
"
complex_queries.convertStringToRegExp():
"
+
"
Optional argument 2 must be a string of length <= 1
"
);
}
return
new
RegExp
(
"
^
"
+
stringEscapeRegexpCharacters
(
string
).
replace
(
new
RegExp
(
stringEscapeRegexpCharacters
(
wildcard_character
),
'
g
'
),
'
.*
'
)
+
"
$
"
);
}
_export
(
'
convertStringToRegExp
'
,
convertStringToRegExp
);
/*jslint indent: 2, maxlen: 80, sloppy: true, nomen: true */
/*global _export: true, ComplexQuery: true, SimpleQuery: true,
newClass: true, Query
: true */
/*global _export: true, ComplexQuery: true, SimpleQuery: true,
Query: true,
parseStringToObject
: true */
var
query_class_dict
=
{}
,
QueryFactory
;
var
query_class_dict
=
{};
/**
* Provides static methods to create Query object
*
* @class QueryFactory
*/
QueryFactory
=
newClass
({
"
static_methods
"
:
{
/**
* Creates Query object from a search text string or a serialized version
* of a Query.
*
* @method create
* @static
* @param {Object,String} object The search text or the serialized version
* of a Query
* @return {Query} A Query object
*/
"
create
"
:
function
(
object
)
{
if
(
object
===
""
)
{
return
new
Query
();
}
if
(
typeof
object
===
"
string
"
)
{
object
=
Query
.
parseStringToObject
(
object
);
}
if
(
typeof
(
object
||
{}).
type
===
"
string
"
&&
query_class_dict
[
object
.
type
])
{
return
new
query_class_dict
[
object
.
type
](
object
);
}
return
null
;
}
function
QueryFactory
()
{}
/**
* Creates Query object from a search text string or a serialized version
* of a Query.
*
* @method create
* @static
* @param {Object,String} object The search text or the serialized version
* of a Query
* @return {Query} A Query object
*/
QueryFactory
.
create
=
function
(
object
)
{
if
(
object
===
""
)
{
return
new
Query
();
}
},
function
()
{});
if
(
typeof
object
===
"
string
"
)
{
object
=
parseStringToObject
(
object
);
}
if
(
typeof
(
object
||
{}).
type
===
"
string
"
&&
query_class_dict
[
object
.
type
])
{
return
new
query_class_dict
[
object
.
type
](
object
);
}
throw
new
TypeError
(
"
QueryFactory.create():
"
+
"
Argument 1 is not a search text or a parsable object
"
);
};
_export
(
"
QueryFactory
"
,
QueryFactory
);
/*jslint indent: 2, maxlen: 80, sloppy: true, nomen: true */
/*global newClass: true, sortFunction: true, parseStringToObject: true,
_export: true, stringEscapeRegexpCharacters: true */
/*global parseStringToObject: true, emptyFunction: true, sortOn: true, limit:
true, select: true, _export: true, stringEscapeRegexpCharacters: true,
deepClone: true */
/**
* The query to use to filter a list of objects.
...
...
@@ -897,99 +1059,7 @@ _export("QueryFactory", QueryFactory);
* @class Query
* @constructor
*/
var
Query
=
newClass
(
function
()
{
var
that
=
this
,
emptyFunction
=
function
()
{};
/**
* Filter the item list with matching item only
*
* @method exec
* @param {Array} item_list The list of object
* @param {Object} [option] Some operation option
* @param {String} [option.wildcard_character="%"] The wildcard character
* @param {Array} [option.select_list] A object keys to retrieve
* @param {Array} [option.sort_on] Couples of object keys and "ascending"
* or "descending"
* @param {Array} [option.limit] Couple of integer, first is an index and
* second is the length.
*/
that
.
exec
=
function
(
item_list
,
option
)
{
var
i
=
0
;
while
(
i
<
item_list
.
length
)
{
if
(
!
that
.
match
(
item_list
[
i
],
option
.
wildcard_character
))
{
item_list
.
splice
(
i
,
1
);
}
else
{
i
+=
1
;
}
}
if
(
option
.
sort_on
)
{
Query
.
sortOn
(
option
.
sort_on
,
item_list
);
}
if
(
option
.
limit
)
{
item_list
.
splice
(
0
,
option
.
limit
[
0
]);
if
(
option
.
limit
[
1
])
{
item_list
.
splice
(
option
.
limit
[
1
]);
}
}
Query
.
filterListSelect
(
option
.
select_list
||
[],
item_list
);
};
/**
* Test if an item matches this query
*
* @method match
* @param {Object} item The object to test
* @return {Boolean} true if match, false otherwise
*/
that
.
match
=
function
(
item
,
wildcard_character
)
{
return
true
;
};
/**
* The recursive parser.
*
* @method recParse
* @private
* @param {Object} object The object shared in the parse process
* @param {Object} options Some options usable in the parseMethods
* @return {Any} The parser result
*/
function
recParse
(
object
,
option
)
{
var
i
,
query
=
object
.
parsed
;
if
(
query
.
type
===
"
complex
"
)
{
for
(
i
=
0
;
i
<
query
.
query_list
.
length
;
i
+=
1
)
{
object
.
parsed
=
query
.
query_list
[
i
];
recParse
(
object
,
option
);
query
.
query_list
[
i
]
=
object
.
parsed
;
}
object
.
parsed
=
query
;
that
.
onParseComplexQuery
(
object
,
option
);
}
else
if
(
query
.
type
===
"
simple
"
)
{
that
.
onParseSimpleQuery
(
object
,
option
);
}
}
/**
* Browse the Query in deep calling parser method in each step.
*
* `onParseStart` is called first, on end `onParseEnd` is called.
* It starts from the simple queries at the bottom of the tree calling the
* parser method `onParseSimpleQuery`, and go up calling the
* `onParseComplexQuery` method.
*
* @method parse
* @param {Object} option Any options you want (except 'parsed')
* @return {Any} The parse result
*/
that
.
parse
=
function
(
option
)
{
var
object
;
object
=
{
"
parsed
"
:
JSON
.
parse
(
JSON
.
stringify
(
that
.
serialized
()))};
that
.
onParseStart
(
object
,
option
);
recParse
(
object
,
option
);
that
.
onParseEnd
(
object
,
option
);
return
object
.
parsed
;
};
function
Query
()
{
/**
* Called before parsing the query. Must be overridden!
...
...
@@ -998,7 +1068,7 @@ var Query = newClass(function () {
* @param {Object} object The object shared in the parse process
* @param {Object} option Some option gave in parse()
*/
th
at
.
onParseStart
=
emptyFunction
;
th
is
.
onParseStart
=
emptyFunction
;
/**
* Called when parsing a simple query. Must be overridden!
...
...
@@ -1007,7 +1077,7 @@ var Query = newClass(function () {
* @param {Object} object The object shared in the parse process
* @param {Object} option Some option gave in parse()
*/
th
at
.
onParseSimpleQuery
=
emptyFunction
;
th
is
.
onParseSimpleQuery
=
emptyFunction
;
/**
* Called when parsing a complex query. Must be overridden!
...
...
@@ -1016,7 +1086,7 @@ var Query = newClass(function () {
* @param {Object} object The object shared in the parse process
* @param {Object} option Some option gave in parse()
*/
th
at
.
onParseComplexQuery
=
emptyFunction
;
th
is
.
onParseComplexQuery
=
emptyFunction
;
/**
* Called after parsing the query. Must be overridden!
...
...
@@ -1025,105 +1095,133 @@ var Query = newClass(function () {
* @param {Object} object The object shared in the parse process
* @param {Object} option Some option gave in parse()
*/
th
at
.
onParseEnd
=
emptyFunction
;
th
is
.
onParseEnd
=
emptyFunction
;
/**
* Convert this query to a parsable string.
*
* @method toString
* @return {String} The string version of this query
*/
that
.
toString
=
function
()
{
return
""
;
};
}
/**
* Convert this query to an jsonable object in order to be remake thanks to
* QueryFactory class.
*
* @method serialized
* @return {Object} The jsonable object
*/
that
.
serialized
=
function
()
{
return
undefined
;
};
/**
* Filter the item list with matching item only
*
* @method exec
* @param {Array} item_list The list of object
* @param {Object} [option] Some operation option
* @param {String} [option.wildcard_character="%"] The wildcard character
* @param {Array} [option.select_list] A object keys to retrieve
* @param {Array} [option.sort_on] Couples of object keys and "ascending"
* or "descending"
* @param {Array} [option.limit] Couple of integer, first is an index and
* second is the length.
*/
Query
.
prototype
.
exec
=
function
(
item_list
,
option
)
{
var
i
=
0
;
if
(
!
Array
.
isArray
(
item_list
))
{
throw
new
TypeError
(
"
Query().exec(): Argument 1 is not of type 'array'
"
);
}
if
(
option
===
undefined
)
{
option
=
{};
}
if
(
typeof
option
!==
'
object
'
)
{
throw
new
TypeError
(
"
Query().exec():
"
+
"
Optional argument 2 is not of type 'object'
"
);
}
if
(
option
.
wildcard_character
===
undefined
)
{
option
.
wildcard_character
=
'
%
'
;
}
while
(
i
<
item_list
.
length
)
{
if
(
!
this
.
match
(
item_list
[
i
],
option
.
wildcard_character
))
{
item_list
.
splice
(
i
,
1
);
}
else
{
i
+=
1
;
}
}
if
(
option
.
sort_on
)
{
sortOn
(
option
.
sort_on
,
item_list
);
}
if
(
option
.
limit
)
{
limit
(
option
.
limit
,
item_list
);
}
select
(
option
.
select_list
||
[],
item_list
);
};
},
{
"
static_methods
"
:
{
/**
* Test if an item matches this query
*
* @method match
* @param {Object} item The object to test
* @return {Boolean} true if match, false otherwise
*/
Query
.
prototype
.
match
=
function
(
item
,
wildcard_character
)
{
return
true
;
};
/**
* Filter a list of items, modifying them to select only wanted keys.
*
* @method filterListSelect
* @static
* @param {Array} select_option Key list to keep
* @param {Array} list The item list to filter
*/
"
filterListSelect
"
:
function
(
select_option
,
list
)
{
var
i
,
j
,
new_item
;
for
(
i
=
0
;
i
<
list
.
length
;
i
+=
1
)
{
new_item
=
{};
for
(
j
=
0
;
j
<
select_option
.
length
;
j
+=
1
)
{
new_item
[
select_option
[
j
]]
=
list
[
i
][
select_option
[
j
]];
}
for
(
j
in
new_item
)
{
if
(
new_item
.
hasOwnProperty
(
j
))
{
list
[
i
]
=
new_item
;
break
;
}
}
}
},
/**
* Browse the Query in deep calling parser method in each step.
*
* `onParseStart` is called first, on end `onParseEnd` is called.
* It starts from the simple queries at the bottom of the tree calling the
* parser method `onParseSimpleQuery`, and go up calling the
* `onParseComplexQuery` method.
*
* @method parse
* @param {Object} option Any options you want (except 'parsed')
* @return {Any} The parse result
*/
Query
.
prototype
.
parse
=
function
(
option
)
{
var
that
=
this
,
object
;
/**
*
Sort a list of items, according to keys and directions
.
*
The recursive parser
.
*
* @method sortOn
* @static
* @param {Array} sort_on_option List of couples [key, direction]
* @param {Array} list The item list to sort
* @param {Object} object The object shared in the parse process
* @param {Object} options Some options usable in the parseMethods
* @return {Any} The parser result
*/
"
sortOn
"
:
function
(
sort_on_option
,
list
)
{
var
sort_index
;
for
(
sort_index
=
sort_on_option
.
length
-
1
;
sort_index
>=
0
;
sort_index
-=
1
)
{
list
.
sort
(
sortFunction
(
sort_on_option
[
sort_index
][
0
],
sort_on_option
[
sort_index
][
1
]
));
function
recParse
(
object
,
option
)
{
var
i
,
query
=
object
.
parsed
;
if
(
query
.
type
===
"
complex
"
)
{
for
(
i
=
0
;
i
<
query
.
query_list
.
length
;
i
+=
1
)
{
object
.
parsed
=
query
.
query_list
[
i
];
recParse
(
object
,
option
);
query
.
query_list
[
i
]
=
object
.
parsed
;
}
object
.
parsed
=
query
;
that
.
onParseComplexQuery
(
object
,
option
);
}
else
if
(
query
.
type
===
"
simple
"
)
{
that
.
onParseSimpleQuery
(
object
,
option
);
}
},
}
object
=
{
"
parsed
"
:
JSON
.
parse
(
JSON
.
stringify
(
that
.
serialized
()))};
that
.
onParseStart
(
object
,
option
);
recParse
(
object
,
option
);
that
.
onParseEnd
(
object
,
option
);
return
object
.
parsed
;
};
/**
* Parse a text request to a json query object tree
*
* @method parseStringToObject
* @static
* @param {String} string The string to parse
* @return {Object} The json query tree
*/
"
parseStringToObject
"
:
parseStringToObject
,
/**
* Convert this query to a parsable string.
*
* @method toString
* @return {String} The string version of this query
*/
Query
.
prototype
.
toString
=
function
()
{
return
""
;
};
/**
* Convert a search text to a regexp.
*
* @method convertStringToRegExp
* @static
* @param {String} string The string to convert
* @param {String} [wildcard_character=undefined] The wildcard chararter
* @return {RegExp} The search text regexp
*/
"
convertStringToRegExp
"
:
function
(
string
,
wildcard_character
)
{
return
new
RegExp
(
"
^
"
+
stringEscapeRegexpCharacters
(
string
).
replace
(
stringEscapeRegexpCharacters
(
wildcard_character
),
'
.*
'
)
+
"
$
"
);
}
}});
/**
* Convert this query to an jsonable object in order to be remake thanks to
* QueryFactory class.
*
* @method serialized
* @return {Object} The jsonable object
*/
Query
.
prototype
.
serialized
=
function
()
{
return
undefined
;
};
_export
(
"
Query
"
,
Query
);
/*jslint indent: 2, maxlen: 80, sloppy: true, nomen: true */
/*global
newClass: true, Query
: true,
query_class_dict: true, _export
: true */
/*global
Query: true, inherits: true, query_class_dict: true, _export
: true,
convertStringToRegExp
: true */
/**
* The SimpleQuery inherits from Query, and compares one metadata value
...
...
@@ -1135,7 +1233,9 @@ _export("Query", Query);
* @param {String} spec.key The metadata key
* @param {String} spec.value The value of the metadata to compare
*/
var
SimpleQuery
=
newClass
(
Query
,
function
(
spec
)
{
function
SimpleQuery
(
spec
)
{
Query
.
call
(
this
);
/**
* Operator to use to compare object values
*
...
...
@@ -1162,124 +1262,206 @@ var SimpleQuery = newClass(Query, function (spec) {
*/
this
.
value
=
spec
.
value
;
/**
* #crossLink "Query/match:method"
*/
this
.
match
=
function
(
item
,
wildcard_character
)
{
return
this
[
this
.
operator
](
item
[
this
.
key
],
this
.
value
,
wildcard_character
);
};
}
inherits
(
SimpleQuery
,
Query
);
/**
* #crossLink "Query/toString:method"
*/
this
.
toString
=
function
()
{
return
(
this
.
key
?
this
.
key
+
"
:
"
:
""
)
+
(
this
.
operator
||
"
=
"
)
+
'
"
'
+
this
.
value
+
'
"
'
;
};
/**
* #crossLink "Query/match:method"
*/
SimpleQuery
.
prototype
.
match
=
function
(
item
,
wildcard_character
)
{
return
this
[
this
.
operator
](
item
[
this
.
key
],
this
.
value
,
wildcard_character
);
};
/**
* #crossLink "Query/serialized:method"
*/
this
.
serialized
=
function
()
{
return
{
"
type
"
:
"
simple
"
,
"
operator
"
:
this
.
operator
,
"
key
"
:
this
.
key
,
"
value
"
:
this
.
value
};
};
/**
* #crossLink "Query/toString:method"
*/
SimpleQuery
.
prototype
.
toString
=
function
()
{
return
(
this
.
key
?
this
.
key
+
"
:
"
:
""
)
+
(
this
.
operator
||
"
=
"
)
+
'
"
'
+
this
.
value
+
'
"
'
;
};
/**
* Comparison operator, test if this query value matches the item value
*
* @method =
* @param {String} object_value The value to compare
* @param {String} comparison_value The comparison value
* @param {String} wildcard_character The wildcard_character
* @return {Boolean} true if match, false otherwise
*/
this
[
"
=
"
]
=
function
(
object_value
,
comparison_value
,
wildcard_character
)
{
return
Query
.
convertStringToRegExp
(
comparison_value
.
toString
(),
wildcard_character
||
"
%
"
).
test
(
object_value
.
toString
());
/**
* #crossLink "Query/serialized:method"
*/
SimpleQuery
.
prototype
.
serialized
=
function
()
{
return
{
"
type
"
:
"
simple
"
,
"
operator
"
:
this
.
operator
,
"
key
"
:
this
.
key
,
"
value
"
:
this
.
value
};
};
/**
* Comparison operator, test if this query value does not match the item value
*
* @method !=
* @param {String} object_value The value to compare
* @param {String} comparison_value The comparison value
* @param {String} wildcard_character The wildcard_character
* @return {Boolean} true if not match, false otherwise
*/
this
[
"
!=
"
]
=
function
(
object_value
,
comparison_value
,
wildcard_character
)
{
return
!
Query
.
convertStringTextToRegExp
(
comparison_value
.
toString
(),
wildcard_character
||
"
%
"
).
test
(
object_value
.
toString
());
};
/**
* Comparison operator, test if this query value matches the item value
*
* @method =
* @param {String} object_value The value to compare
* @param {String} comparison_value The comparison value
* @param {String} wildcard_character The wildcard_character
* @return {Boolean} true if match, false otherwise
*/
SimpleQuery
.
prototype
[
"
=
"
]
=
function
(
object_value
,
comparison_value
,
wildcard_character
)
{
var
value
,
i
;
if
(
!
Array
.
isArray
(
object_value
))
{
object_value
=
[
object_value
];
}
for
(
i
=
0
;
i
<
object_value
.
length
;
i
+=
1
)
{
value
=
object_value
[
i
];
if
(
typeof
value
===
'
object
'
)
{
value
=
value
.
content
;
}
if
(
comparison_value
===
undefined
)
{
if
(
value
===
undefined
)
{
return
true
;
}
return
false
;
}
if
(
value
===
undefined
)
{
return
false
;
}
if
(
convertStringToRegExp
(
comparison_value
.
toString
(),
wildcard_character
).
test
(
value
.
toString
())
)
{
return
true
;
}
}
return
false
;
};
/**
* Comparison operator, test if this query value is lower than the item value
*
* @method <
* @param {Number, String} object_value The value to compare
* @param {Number, String} comparison_value The comparison value
* @return {Boolean} true if lower, false otherwise
*/
this
[
"
<
"
]
=
function
(
object_value
,
comparison_value
)
{
return
object_value
<
comparison_value
;
};
/**
* Comparison operator, test if this query value does not match the item value
*
* @method !=
* @param {String} object_value The value to compare
* @param {String} comparison_value The comparison value
* @param {String} wildcard_character The wildcard_character
* @return {Boolean} true if not match, false otherwise
*/
SimpleQuery
.
prototype
[
"
!=
"
]
=
function
(
object_value
,
comparison_value
,
wildcard_character
)
{
var
value
,
i
;
if
(
!
Array
.
isArray
(
object_value
))
{
object_value
=
[
object_value
];
}
for
(
i
=
0
;
i
<
object_value
.
length
;
i
+=
1
)
{
value
=
object_value
[
i
];
if
(
typeof
value
===
'
object
'
)
{
value
=
value
.
content
;
}
if
(
comparison_value
===
undefined
)
{
if
(
value
===
undefined
)
{
return
false
;
}
return
true
;
}
if
(
value
===
undefined
)
{
return
true
;
}
if
(
convertStringToRegExp
(
comparison_value
.
toString
(),
wildcard_character
).
test
(
value
.
toString
())
)
{
return
false
;
}
}
return
true
;
};
/**
* Comparison operator, test if this query value is equal or lower than the
* item value
*
* @method <=
* @param {Number, String} object_value The value to compare
* @param {Number, String} comparison_value The comparison value
* @return {Boolean} true if equal or lower, false otherwise
*/
this
[
"
<=
"
]
=
function
(
object_value
,
comparison_value
)
{
return
object_value
<=
comparison_value
;
};
/**
* Comparison operator, test if this query value is lower than the item value
*
* @method <
* @param {Number, String} object_value The value to compare
* @param {Number, String} comparison_value The comparison value
* @return {Boolean} true if lower, false otherwise
*/
SimpleQuery
.
prototype
[
"
<
"
]
=
function
(
object_value
,
comparison_value
)
{
var
value
;
if
(
!
Array
.
isArray
(
object_value
))
{
object_value
=
[
object_value
];
}
value
=
object_value
[
0
];
if
(
typeof
value
===
'
object
'
)
{
value
=
value
.
content
;
}
return
value
<
comparison_value
;
};
/**
* Comparison operator, test if this query value is greater than the item
* value
*
* @method >
* @param {Number, String} object_value The value to compare
* @param {Number, String} comparison_value The comparison value
* @return {Boolean} true if greater, false otherwise
*/
this
[
"
>
"
]
=
function
(
object_value
,
comparison_value
)
{
return
object_value
>
comparison_value
;
};
/**
* Comparison operator, test if this query value is equal or lower than the
* item value
*
* @method <=
* @param {Number, String} object_value The value to compare
* @param {Number, String} comparison_value The comparison value
* @return {Boolean} true if equal or lower, false otherwise
*/
SimpleQuery
.
prototype
[
"
<=
"
]
=
function
(
object_value
,
comparison_value
)
{
var
value
;
if
(
!
Array
.
isArray
(
object_value
))
{
object_value
=
[
object_value
];
}
value
=
object_value
[
0
];
if
(
typeof
value
===
'
object
'
)
{
value
=
value
.
content
;
}
return
value
<=
comparison_value
;
};
/**
* Comparison operator, test if this query value is equal or greater than the
* item value
*
* @method >=
* @param {Number, String} object_value The value to compare
* @param {Number, String} comparison_value The comparison value
* @return {Boolean} true if equal or greater, false otherwise
*/
this
[
"
>=
"
]
=
function
(
object_value
,
comparison_value
)
{
return
object_value
>=
comparison_value
;
};
});
/**
* Comparison operator, test if this query value is greater than the item
* value
*
* @method >
* @param {Number, String} object_value The value to compare
* @param {Number, String} comparison_value The comparison value
* @return {Boolean} true if greater, false otherwise
*/
SimpleQuery
.
prototype
[
"
>
"
]
=
function
(
object_value
,
comparison_value
)
{
var
value
;
if
(
!
Array
.
isArray
(
object_value
))
{
object_value
=
[
object_value
];
}
value
=
object_value
[
0
];
if
(
typeof
value
===
'
object
'
)
{
value
=
value
.
content
;
}
return
value
>
comparison_value
;
};
/**
* Comparison operator, test if this query value is equal or greater than the
* item value
*
* @method >=
* @param {Number, String} object_value The value to compare
* @param {Number, String} comparison_value The comparison value
* @return {Boolean} true if equal or greater, false otherwise
*/
SimpleQuery
.
prototype
[
"
>=
"
]
=
function
(
object_value
,
comparison_value
)
{
var
value
;
if
(
!
Array
.
isArray
(
object_value
))
{
object_value
=
[
object_value
];
}
value
=
object_value
[
0
];
if
(
typeof
value
===
'
object
'
)
{
value
=
value
.
content
;
}
return
value
>=
comparison_value
;
};
query_class_dict
.
simple
=
SimpleQuery
;
_export
(
"
SimpleQuery
"
,
SimpleQuery
);
/*jslint indent: 2, maxlen: 80, sloppy: true, nomen: true */
/*global
newClass: true, Query: true, query_class_dict
: true,
/*global
Query: true, query_class_dict: true, inherits
: true,
_export: true, QueryFactory: true */
/**
...
...
@@ -1293,7 +1475,8 @@ _export("SimpleQuery", SimpleQuery);
* @param {String} spec.key The metadata key
* @param {String} spec.value The value of the metadata to compare
*/
var
ComplexQuery
=
newClass
(
Query
,
function
(
spec
)
{
function
ComplexQuery
(
spec
)
{
Query
.
call
(
this
);
/**
* Logical operator to use to compare object values
...
...
@@ -1316,100 +1499,102 @@ var ComplexQuery = newClass(Query, function (spec) {
this
.
query_list
=
spec
.
query_list
||
[];
this
.
query_list
=
this
.
query_list
.
map
(
QueryFactory
.
create
);
/**
* #crossLink "Query/match:method"
*/
this
.
match
=
function
(
item
,
wildcard_character
)
{
return
this
[
this
.
operator
](
item
,
wildcard_character
);
};
}
inherits
(
ComplexQuery
,
Query
);
/**
* #crossLink "Query/toString:method"
*/
this
.
toString
=
function
()
{
var
str_list
=
[
"
(
"
],
this_operator
=
this
.
operator
;
this
.
query_list
.
forEach
(
function
(
query
)
{
str_list
.
push
(
query
.
toString
());
str_list
.
push
(
this_operator
);
});
str_list
.
pop
();
// remove last operator
str_list
.
push
(
"
)
"
);
return
str_list
.
join
(
"
"
);
};
/**
* #crossLink "Query/match:method"
*/
ComplexQuery
.
prototype
.
match
=
function
(
item
,
wildcard_character
)
{
return
this
[
this
.
operator
](
item
,
wildcard_character
);
};
/**
* #crossLink "Query/serialized:method"
*/
this
.
serialized
=
function
()
{
var
s
=
{
"
type
"
:
"
complex
"
,
"
operator
"
:
this
.
operator
,
"
query_list
"
:
[]
};
this
.
query_list
.
forEach
(
function
(
query
)
{
s
.
query_list
.
push
(
query
.
serialized
());
});
return
s
;
/**
* #crossLink "Query/toString:method"
*/
ComplexQuery
.
prototype
.
toString
=
function
()
{
var
str_list
=
[
"
(
"
],
this_operator
=
this
.
operator
;
this
.
query_list
.
forEach
(
function
(
query
)
{
str_list
.
push
(
query
.
toString
());
str_list
.
push
(
this_operator
);
});
str_list
.
pop
();
// remove last operator
str_list
.
push
(
"
)
"
);
return
str_list
.
join
(
"
"
);
};
/**
* #crossLink "Query/serialized:method"
*/
ComplexQuery
.
prototype
.
serialized
=
function
()
{
var
s
=
{
"
type
"
:
"
complex
"
,
"
operator
"
:
this
.
operator
,
"
query_list
"
:
[]
};
this
.
query_list
.
forEach
(
function
(
query
)
{
s
.
query_list
.
push
(
query
.
serialized
());
});
return
s
;
};
/**
* Comparison operator, test if all sub queries match the
* item value
*
* @method AND
* @param {Object} item The item to match
* @param {String} wildcard_character The wildcard character
* @return {Boolean} true if all match, false otherwise
*/
this
.
AND
=
function
(
item
,
wildcard_character
)
{
var
i
;
for
(
i
=
0
;
i
<
this
.
query_list
.
length
;
i
+=
1
)
{
if
(
!
this
.
query_list
[
i
].
match
(
item
,
wildcard_character
))
{
return
false
;
}
/**
* Comparison operator, test if all sub queries match the
* item value
*
* @method AND
* @param {Object} item The item to match
* @param {String} wildcard_character The wildcard character
* @return {Boolean} true if all match, false otherwise
*/
ComplexQuery
.
prototype
.
AND
=
function
(
item
,
wildcard_character
)
{
var
i
;
for
(
i
=
0
;
i
<
this
.
query_list
.
length
;
i
+=
1
)
{
if
(
!
this
.
query_list
[
i
].
match
(
item
,
wildcard_character
))
{
return
false
;
}
return
true
;
};
}
return
true
;
};
/**
* Comparison operator, test if one of the sub queries matches the
* item value
*
* @method OR
* @param {Object} item The item to match
* @param {String} wildcard_character The wildcard character
* @return {Boolean} true if one match, false otherwise
*/
this
.
OR
=
function
(
item
,
wildcard_character
)
{
var
i
;
for
(
i
=
0
;
i
<
this
.
query_list
.
length
;
i
+=
1
)
{
if
(
this
.
query_list
[
i
].
match
(
item
,
wildcard_character
))
{
return
true
;
}
/**
* Comparison operator, test if one of the sub queries matches the
* item value
*
* @method OR
* @param {Object} item The item to match
* @param {String} wildcard_character The wildcard character
* @return {Boolean} true if one match, false otherwise
*/
ComplexQuery
.
prototype
.
OR
=
function
(
item
,
wildcard_character
)
{
var
i
;
for
(
i
=
0
;
i
<
this
.
query_list
.
length
;
i
+=
1
)
{
if
(
this
.
query_list
[
i
].
match
(
item
,
wildcard_character
))
{
return
true
;
}
return
false
;
};
}
return
false
;
};
/**
* Comparison operator, test if the sub query does not match the
* item value
*
* @method NOT
* @param {Object} item The item to match
* @param {String} wildcard_character The wildcard character
* @return {Boolean} true if one match, false otherwise
*/
this
.
NOT
=
function
(
item
,
wildcard_character
)
{
return
!
this
.
query_list
[
0
].
match
(
item
,
wildcard_character
);
};
});
/**
* Comparison operator, test if the sub query does not match the
* item value
*
* @method NOT
* @param {Object} item The item to match
* @param {String} wildcard_character The wildcard character
* @return {Boolean} true if one match, false otherwise
*/
ComplexQuery
.
prototype
.
NOT
=
function
(
item
,
wildcard_character
)
{
return
!
this
.
query_list
[
0
].
match
(
item
,
wildcard_character
);
};
query_class_dict
.
complex
=
ComplexQuery
;
_export
(
"
ComplexQuery
"
,
ComplexQuery
);
if
(
typeof
define
===
"
function
"
&&
define
.
amd
)
{
//
define(to_export);
//
define(to_export);
Object
.
defineProperty
(
window
,
module_name
,
{
configurable
:
false
,
enumerable
:
true
,
...
...
js/libs/jio/indexstorage.js
View file @
5717cd1d
...
...
@@ -401,7 +401,7 @@
*/
function
indexStorage
(
spec
,
my
)
{
var
that
,
priv
=
{};
that
=
my
.
basicStorage
(
spec
,
my
);
priv
.
indices
=
spec
.
indices
;
...
...
@@ -744,7 +744,7 @@
if
(
just_check
)
{
priv
.
getIndexDatabase
(
option
,
index
,
function
(
current_db
)
{
if
(
db
.
equals
(
current_db
))
{
return
that
.
success
({
"
ok
"
:
true
,
"
_
id
"
:
command
.
getDocId
()});
return
that
.
success
({
"
ok
"
:
true
,
"
id
"
:
command
.
getDocId
()});
}
return
that
.
error
(
generateErrorObject
(
"
Different Index
"
,
...
...
@@ -754,7 +754,7 @@
});
}
else
{
priv
.
storeIndexDatabaseList
(
db_list
,
{},
function
()
{
that
.
success
({
"
ok
"
:
true
,
"
_
id
"
:
command
.
getDocId
()});
that
.
success
({
"
ok
"
:
true
,
"
id
"
:
command
.
getDocId
()});
});
}
},
...
...
js/libs/jio/jio.js
View file @
5717cd1d
...
...
@@ -531,13 +531,13 @@ var command = function (spec, my) {
* @param {object} storage The storage.
*/
that
.
validate
=
function
(
storage
)
{
if
(
typeof
priv
.
doc
.
_id
===
"
string
"
&&
priv
.
doc
.
_id
.
match
(
"
"
)
)
{
if
(
typeof
priv
.
doc
.
_id
===
"
string
"
&&
priv
.
doc
.
_id
===
""
)
{
that
.
error
({
"
status
"
:
21
,
"
statusText
"
:
"
Invalid Document Id
"
,
"
error
"
:
"
invalid_document_id
"
,
"
message
"
:
"
The document id is invalid
"
,
"
reason
"
:
"
The document id contains spaces
"
"
reason
"
:
"
empty
"
});
return
false
;
}
...
...
js/libs/jio/localstorage.js
View file @
5717cd1d
...
...
@@ -11,6 +11,37 @@
/**
* JIO Local Storage. Type = 'local'.
* Local browser "database" storage.
*
* Storage Description:
*
* {
* "type": "local",
* "username": <non empty string>, // to define user space
* "application_name": <string> // default 'untitled'
* }
*
* Document are stored in path
* 'jio/localstorage/username/application_name/document_id' like this:
*
* {
* "_id": "document_id",
* "_attachments": {
* "attachment_name": {
* "length": data_length,
* "digest": "md5-XXX",
* "content_type": "mime/type"
* },
* "attachment_name2": {..}, ...
* },
* "metadata_name": "metadata_value"
* "metadata_name2": ...
* ...
* }
*
* Only "_id" and "_attachments" are specific metadata keys, other one can be
* added without loss.
*
* @class LocalStorage
*/
jIO
.
addStorageType
(
'
local
'
,
function
(
spec
,
my
)
{
...
...
@@ -64,34 +95,6 @@ jIO.addStorageType('local', function (spec, my) {
S4
()
+
S4
();
};
/**
* Update [doc] the document object and remove [doc] keys
* which are not in [new_doc]. It only changes [doc] keys not starting
* with an underscore.
* ex: doc: {key:value1,_key:value2} with
* new_doc: {key:value3,_key:value4} updates
* doc: {key:value3,_key:value2}.
* @param {object} doc The original document object.
* @param {object} new_doc The new document object
*/
priv
.
documentObjectUpdate
=
function
(
doc
,
new_doc
)
{
var
k
;
for
(
k
in
doc
)
{
if
(
doc
.
hasOwnProperty
(
k
))
{
if
(
k
[
0
]
!==
'
_
'
)
{
delete
doc
[
k
];
}
}
}
for
(
k
in
new_doc
)
{
if
(
new_doc
.
hasOwnProperty
(
k
))
{
if
(
k
[
0
]
!==
'
_
'
)
{
doc
[
k
]
=
new_doc
[
k
];
}
}
}
};
/**
* Checks if an object has no enumerable keys
* @method objectIsEmpty
...
...
@@ -137,11 +140,11 @@ jIO.addStorageType('local', function (spec, my) {
}
doc
=
localstorage
.
getItem
(
priv
.
localpath
+
"
/
"
+
doc_id
);
if
(
doc
===
null
)
{
// the document does not exist
doc
=
command
.
cloneDoc
();
doc
.
_id
=
doc_id
;
// the document does not exist
localstorage
.
setItem
(
priv
.
localpath
+
"
/
"
+
doc_id
,
doc
);
delete
doc
.
_attachments
;
localstorage
.
setItem
(
priv
.
localpath
+
"
/
"
+
doc_id
,
doc
);
that
.
success
({
"
ok
"
:
true
,
"
id
"
:
doc_id
...
...
@@ -166,14 +169,17 @@ jIO.addStorageType('local', function (spec, my) {
*/
that
.
put
=
function
(
command
)
{
setTimeout
(
function
()
{
var
doc
;
var
doc
,
tmp
;
doc
=
localstorage
.
getItem
(
priv
.
localpath
+
"
/
"
+
command
.
getDocId
());
if
(
doc
===
null
)
{
// the document does not exist
doc
=
command
.
cloneDoc
();
delete
doc
.
_attachments
;
}
else
{
// the document already exists
priv
.
documentObjectUpdate
(
doc
,
command
.
cloneDoc
());
tmp
=
command
.
cloneDoc
();
tmp
.
_attachments
=
doc
.
_attachments
;
doc
=
tmp
;
}
// write
localstorage
.
setItem
(
priv
.
localpath
+
"
/
"
+
command
.
getDocId
(),
doc
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment