Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ Basic use cases:
var observable = ko.wrap.fromJS(JSObjects);

var jsObjects = ko.wrap.toJS(observable);
var jsObjects = ko.wrap.toJS(observable, { includeComputed: true, ignore: ['__ko_mapping__', 'someProp'] });

Please note that if you are updating an observable, then it's
preferable to use ko.wrap.updateFromJS(observable, jsObject).
Expand Down
22 changes: 22 additions & 0 deletions bower.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
"name": "knockout.wrap",
"description": "Simple fast js to ko and ko to js mapper",
"main": "knockout.wrap.js",
"authors": [
"Anders Rune Jensen"
],
"license": "MIT",
"keywords": [
"knockout",
"mapping",
"wrap",
"fast"
],
"ignore": [
"**/.*",
"node_modules",
"bower_components",
"tests",
"*.nupkg"
]
}
Binary file added knockout.wrap.1.0.2.nupkg
Binary file not shown.
254 changes: 114 additions & 140 deletions knockout.wrap.js
Original file line number Diff line number Diff line change
@@ -1,209 +1,183 @@
// Knockout Fast Mapping v0.1
// Knockout Fast Mapping v1.0.2
// License: MIT (http://www.opensource.org/licenses/mit-license.php)

(function (factory) {
// Module systems magic dance.

if (typeof require === "function" && typeof exports === "object" && typeof module === "object") {
// CommonJS or Node: hard-coded dependency on "knockout"
factory(require("knockout"), exports);
} else if (typeof define === "function" && define["amd"]) {
// AMD anonymous module with hard-coded dependency on "knockout"
define(["knockout", "exports"], factory);
} else {
// <script> tag: use the global `ko` object, attaching a `wrap` property
factory(ko, ko.wrap = {});
}
}(function (ko, exports) {

// this function mimics ko.mapping
exports.fromJS = function(jsObject, computedFunctions)
{
reset();
return wrap(jsObject, computedFunctions);
(function(factory) {
// Module systems magic dance.

if (typeof require === "function" && typeof exports === "object" && typeof module === "object") {
// CommonJS or Node: hard-coded dependency on "knockout"
factory(require("knockout"), exports);
} else if (typeof define === "function" && define["amd"]) {
// AMD anonymous module with hard-coded dependency on "knockout"
define(["knockout", "exports"], factory);
} else {
// <script> tag: use the global `ko` object, attaching a `wrap` property
factory(ko, ko.wrap = {});
}
}(function(ko, exports) {

// this function unwraps the outer for assigning the result to an observable
// this function mimics ko.mapping
exports.fromJS = function(jsObject, computedFunctions) {
reset();
return wrap(jsObject, computedFunctions);
}; // this function unwraps the outer for assigning the result to an observable
// see https://github.com/SteveSanderson/knockout/issues/517
exports.updateFromJS = function(observable, jsObject, computedFunctions)
{
exports.updateFromJS = function(observable, jsObject, computedFunctions) {
reset();
return observable(ko.utils.unwrapObservable(wrap(jsObject, computedFunctions)));
}

exports.fromJSON = function (jsonString, computedFunctions) {
var parsed = ko.utils.parseJson(jsonString);
arguments[0] = parsed;
return exports.fromJS.apply(this, computedFunctions);
return observable(ko.utils.unwrapObservable(wrap(jsObject, computedFunctions)));
};
exports.fromJSON = function(jsonString, computedFunctions) {
var parsed = ko.utils.parseJson(jsonString);
arguments[0] = parsed;
return exports.fromJS.apply(this, computedFunctions);
};

exports.toJS = function (observable) {
return unwrap(observable);
}

exports.toJSON = function (observable) {
var plainJavaScriptObject = exports.toJS(observable);
return ko.utils.stringifyJson(plainJavaScriptObject);
exports.toJS = function (observable, options) {
var defaultOptions = { ignore: ['__ko_mapping__'], includeComputed: false };
options = ko.utils.extend(defaultOptions, options);
return unwrap(observable, options);
};
exports.toJSON = function (observable, options) {
var plainJavaScriptObject = exports.toJS(observable, options);
return ko.utils.stringifyJson(plainJavaScriptObject);
};

function typeOf(value) {
var s = typeof value;
if (s === 'object') {
var s = typeof value;
if (s === "object") {
if (value) {
if (value.constructor == Date)
s = 'date';
else if (Object.prototype.toString.call(value) == '[object Array]')
s = 'array';
s = "date";
else if (Object.prototype.toString.call(value) == "[object Array]")
s = "array";
} else {
s = 'null';
s = "null";
}
}
return s;
}
return s;
}

// unwrapping
function unwrapObject(o)
{
var t = {};
function unwrapObject(o, opts) {
var ignore = opts && opts.ignore ? opts.ignore : [];
var includeComputed = opts && opts.includeComputed;
var t = {};

for (var k in o) {
var v = o[k];

for (var k in o)
{
var v = o[k];
// ignore properties in the ignore array and computed observables if includeComputed is false
if ((ko.isComputed(v) && !includeComputed) || ignore.indexOf(k) !== (-1))
continue;

if (ko.isComputed(v))
continue;
t[k] = unwrap(v, opts);
}

return t;
}

t[k] = unwrap(v);
}
function unwrapArray(a, opts) {
var r = [];

return t;
if (!a || a.length == 0)
return r;

for (var i = 0, l = a.length; i < l; ++i)
r.push(unwrap(a[i], opts));

return r;
}

function unwrapArray(a)
{
var r = [];
function unwrap(v, opts) {
var isObservable = ko.isObservable(v);

if (!a || a.length == 0)
return r;

for (var i = 0, l = a.length; i < l; ++i)
r.push(unwrap(a[i]));
if (isObservable) {
var val = v();

return r;
return unwrap(val, opts);
} else {
if (typeOf(v) == "array") {
return unwrapArray(v, opts);
} else if (typeOf(v) == "object") {
return unwrapObject(v, opts);
} else {
return v;
}
}
}

function unwrap(v)
{
var isObservable = ko.isObservable(v);

if (isObservable)
{
var val = v();

return unwrap(val);
}
else
{
if (typeOf(v) == "array")
{
return unwrapArray(v);
}
else if (typeOf(v) == "object")
{
return unwrapObject(v);
}
else
{
return v;
}
}
function reset() {
parents = [{ obj: null, wrapped: null, lvl: "" }];
}

function reset()
{
parents = [{obj: null, wrapped: null, lvl: ""}];
}

// wrapping

function wrapObject(o, computedFunctions)
{
function wrapObject(o, computedFunctions) {
// check for infinite recursion
for (var i = 0; i < parents.length; ++i) {
if (parents[i].obj === o) {
return parents[i].wrapped;
}
}

var t = {};
var t = {};

for (var k in o)
{
var v = o[k];
for (var k in o) {
var v = o[k];

parents.push({obj: o, wrapped: t, lvl: currentLvl() + "/" + k});
parents.push({ obj: o, wrapped: t, lvl: currentLvl() + "/" + k });

t[k] = wrap(v, computedFunctions);
t[k] = wrap(v, computedFunctions);

parents.pop();
}
}

if (computedFunctions && computedFunctions[currentLvl()])
t = computedFunctions[currentLvl()](t);
if (computedFunctions && computedFunctions[currentLvl()])
t = computedFunctions[currentLvl()](t);

if (hasES5Plugin())
ko.track(t);

return t;
return t;
}

function wrapArray(a, computedFunctions)
{
var r = ko.observableArray();
function wrapArray(a, computedFunctions) {
var r = ko.observableArray();

if (!a || a.length == 0)
return r;
if (!a || a.length == 0)
return r;

for (var i = 0, l = a.length; i < l; ++i)
r.push(wrap(a[i], computedFunctions));
for (var i = 0, l = a.length; i < l; ++i)
r.push(wrap(a[i], computedFunctions));

return r;
return r;
}

// a stack, used for two purposes:
// - circular reference checking
// - computed functions
var parents;

function currentLvl()
{
return parents[parents.length-1].lvl;
function currentLvl() {
return parents[parents.length - 1].lvl;
}

function wrap(v, computedFunctions)
{
if (typeOf(v) == "array")
{
return wrapArray(v, computedFunctions);
}
else if (typeOf(v) == "object")
{
return wrapObject(v, computedFunctions);
}
else
{
if (!hasES5Plugin() && typeof v !== 'function')
{
var t = ko.observable();
t(v);
return t;
function wrap(v, computedFunctions) {
if (typeOf(v) == "array") {
return wrapArray(v, computedFunctions);
} else if (typeOf(v) == "object") {
return wrapObject(v, computedFunctions);
} else {
if (!hasES5Plugin() && typeof v !== "function") {
var t = ko.observable();
t(v);
return t;
} else
return v;
}
}
}

function hasES5Plugin()
{
function hasES5Plugin() {
return ko.track != null;
}
}));
}));
8 changes: 8 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"name": "knockout.wrap",
"version": "1.0.2",
"description": "Simple fast js to ko and ko to js mapper",
"main": "knockout.wrap.js",
"author": "Anders Rune Jensen",
"license": "MIT"
}