knockoutjs-rails 1.03 → 1.04

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -20,7 +20,7 @@ Add the following directive to your Javascript manifest file (application.js):
20
20
 
21
21
  ## Versioning
22
22
 
23
- knockoutjs-rails 1.03 == Knockout.js 1.03
23
+ knockoutjs-rails 1.04 == Knockout.js 1.04
24
24
 
25
25
  Every attempt is made to mirror the currently shipping Knockout.js version number wherever possible.
26
26
  The major and minor version numbers will always represent the Knockout.js version, but the patch level
@@ -1,5 +1,5 @@
1
1
  module Knockoutjs
2
2
  module Rails
3
- VERSION = "1.03"
3
+ VERSION = "1.04"
4
4
  end
5
5
  end
@@ -1,4 +1,4 @@
1
- // Knockout JavaScript library v1.03
1
+ // Knockout JavaScript library v1.04
2
2
  // (c) 2010 Steven Sanderson - http://knockoutjs.com/
3
3
  // License: Ms-Pl (http://www.opensource.org/licenses/ms-pl.html)
4
4
 
@@ -7,8 +7,10 @@ var ko = window.ko = {};
7
7
 
8
8
  ko.utils = new (function () {
9
9
  var stringTrimRegex = /^(\s|\u00A0)+|(\s|\u00A0)+$/g;
10
-
10
+
11
11
  return {
12
+ fieldsIncludedWithJsonPost: ['authenticity_token', /^__RequestVerificationToken(_.*)?$/],
13
+
12
14
  arrayForEach: function (array, action) {
13
15
  for (var i = 0, j = array.length; i < j; i++)
14
16
  action(array[i]);
@@ -219,6 +221,27 @@ ko.utils = new (function () {
219
221
  result.push(i);
220
222
  return result;
221
223
  },
224
+
225
+ makeArray: function(arrayLikeObject) {
226
+ var result = [];
227
+ for (var i = arrayLikeObject.length - 1; i >= 0; i--){
228
+ result.push(arrayLikeObject[i]);
229
+ };
230
+ return result;
231
+ },
232
+
233
+ getFormFields: function(form, fieldName) {
234
+ var fields = ko.utils.makeArray(form.getElementsByTagName("INPUT")).concat(ko.utils.makeArray(form.getElementsByTagName("TEXTAREA")));
235
+ var isMatchingField = (typeof fieldName == 'string')
236
+ ? function(field) { return field.name === fieldName }
237
+ : function(field) { return fieldName.test(field.name) }; // Treat fieldName as regex or object containing predicate
238
+ var matches = [];
239
+ for (var i = fields.length - 1; i >= 0; i--) {
240
+ if (isMatchingField(fields[i]))
241
+ matches.push(fields[i]);
242
+ };
243
+ return matches;
244
+ },
222
245
 
223
246
  stringifyJson: function (data) {
224
247
  if ((typeof JSON == "undefined") || (typeof JSON.stringify == "undefined"))
@@ -226,7 +249,23 @@ ko.utils = new (function () {
226
249
  return JSON.stringify(ko.utils.unwrapObservable(data));
227
250
  },
228
251
 
229
- postJson: function (url, data) {
252
+ postJson: function (urlOrForm, data, options) {
253
+ options = options || {};
254
+ var params = options.params || {};
255
+ var includeFields = options.includeFields || this.fieldsIncludedWithJsonPost;
256
+ var url = urlOrForm;
257
+
258
+ // If we were given a form, use its 'action' URL and pick out any requested field values
259
+ if((typeof urlOrForm == 'object') && (urlOrForm.tagName == "FORM")) {
260
+ var originalForm = urlOrForm;
261
+ url = originalForm.action;
262
+ for (var i = includeFields.length - 1; i >= 0; i--) {
263
+ var fields = ko.utils.getFormFields(originalForm, includeFields[i]);
264
+ for (var j = fields.length - 1; j >= 0; j--)
265
+ params[fields[j].name] = fields[j].value;
266
+ }
267
+ }
268
+
230
269
  data = ko.utils.unwrapObservable(data);
231
270
  var form = document.createElement("FORM");
232
271
  form.style.display = "none";
@@ -238,8 +277,14 @@ ko.utils = new (function () {
238
277
  input.value = ko.utils.stringifyJson(ko.utils.unwrapObservable(data[key]));
239
278
  form.appendChild(input);
240
279
  }
280
+ for (var key in params) {
281
+ var input = document.createElement("INPUT");
282
+ input.name = key;
283
+ input.value = params[key];
284
+ form.appendChild(input);
285
+ }
241
286
  document.body.appendChild(form);
242
- form.submit();
287
+ options.submitter ? options.submitter(form) : form.submit();
243
288
  setTimeout(function () { form.parentNode.removeChild(form); }, 0);
244
289
  },
245
290
 
@@ -482,6 +527,25 @@ ko.observableArray = function (initialValues) {
482
527
  return ko.utils.arrayIndexOf(arrayOfValues, value) >= 0;
483
528
  });
484
529
  };
530
+
531
+ result.destroy = function (valueOrPredicate) {
532
+ var underlyingArray = result();
533
+ var predicate = typeof valueOrPredicate == "function" ? valueOrPredicate : function (value) { return value === valueOrPredicate; };
534
+ for (var i = underlyingArray.length - 1; i >= 0; i--) {
535
+ var value = underlyingArray[i];
536
+ if (predicate(value))
537
+ underlyingArray[i]._destroy = true;
538
+ }
539
+ result.valueHasMutated();
540
+ };
541
+
542
+ result.destroyAll = function (arrayOfValues) {
543
+ if (!arrayOfValues)
544
+ return [];
545
+ return result.destroy(function (value) {
546
+ return ko.utils.arrayIndexOf(arrayOfValues, value) >= 0;
547
+ });
548
+ };
485
549
 
486
550
  result.indexOf = function (item) {
487
551
  var underlyingArray = result();
@@ -715,7 +779,7 @@ ko.bindingHandlers.submit = {
715
779
  if (typeof value != "function")
716
780
  throw new Error("The value for a submit binding must be a function to invoke on submit");
717
781
  ko.utils.registerEventHandler(element, "submit", function (event) {
718
- try { value.call(viewModel); }
782
+ try { value.call(viewModel, element); }
719
783
  finally {
720
784
  if (event.preventDefault)
721
785
  event.preventDefault();
@@ -1058,7 +1122,12 @@ ko.templateRewriting = (function () {
1058
1122
  if (typeof unwrappedArray.length == "undefined") // Coerce single value into array
1059
1123
  unwrappedArray = [unwrappedArray];
1060
1124
 
1061
- ko.utils.setDomNodeChildrenFromArrayMapping(targetNode, unwrappedArray, function (arrayValue) {
1125
+ // Filter out any entries marked as destroyed
1126
+ var filteredArray = ko.utils.arrayFilter(unwrappedArray, function(item) {
1127
+ return options.includeDestroyed || !item._destroy;
1128
+ });
1129
+
1130
+ ko.utils.setDomNodeChildrenFromArrayMapping(targetNode, filteredArray, function (arrayValue) {
1062
1131
  return executeTemplate(null, "ignoreTargetNode", template, arrayValue, options);
1063
1132
  }, options);
1064
1133
  }, null, { disposeWhen: whenToDispose });
@@ -1070,7 +1139,7 @@ ko.templateRewriting = (function () {
1070
1139
 
1071
1140
  if (typeof bindingValue.foreach != "undefined") {
1072
1141
  // Render once for each data point
1073
- ko.renderTemplateForEach(templateName, bindingValue.foreach || [], { afterAdd: bindingValue.afterAdd, beforeRemove: bindingValue.beforeRemove }, element);
1142
+ ko.renderTemplateForEach(templateName, bindingValue.foreach || [], { afterAdd: bindingValue.afterAdd, beforeRemove: bindingValue.beforeRemove, includeDestroyed: bindingValue.includeDestroyed }, element);
1074
1143
  }
1075
1144
  else {
1076
1145
  // Render once for this single data point (or use the viewModel if no data was provided)
@@ -1262,14 +1331,17 @@ ko.jqueryTmplTemplateEngine = function () {
1262
1331
  return templateNode;
1263
1332
  }
1264
1333
 
1334
+ var aposMarker = "__ko_apos__";
1335
+ var aposRegex = new RegExp(aposMarker, "g");
1265
1336
  this.renderTemplate = function (template, data, options) {
1266
1337
  // jquery.tmpl doesn't like it if the template returns just text content or nothing - it only likes you to return DOM nodes.
1267
1338
  // To make things more flexible, we can wrap the whole template in a <script> node so that jquery.tmpl just processes it as
1268
1339
  // text and doesn't try to parse the output. Then, since jquery.tmpl has jQuery as a dependency anyway, we can use jQuery to
1269
- // parse that text into a document fragment using jQuery.clean().
1270
- var templateTextInWrapper = "<script type=\"text/html\">" + ko.utils.stringTrim(getTemplateNode(template).text) + "</script>";
1340
+ // parse that text into a document fragment using jQuery.clean().
1341
+ var templateTextInWrapper = "<script type=\"text/html\">" + getTemplateNode(template).text + "</script>";
1271
1342
  var renderedMarkupInWrapper = $.tmpl(templateTextInWrapper, data);
1272
- return jQuery.clean([renderedMarkupInWrapper[0].text], document);
1343
+ var renderedMarkup = renderedMarkupInWrapper[0].text.replace(aposRegex, "'");
1344
+ return jQuery.clean([renderedMarkup], document);
1273
1345
  },
1274
1346
 
1275
1347
  this.isTemplateRewritten = function (template) {
@@ -1278,7 +1350,19 @@ ko.jqueryTmplTemplateEngine = function () {
1278
1350
 
1279
1351
  this.rewriteTemplate = function (template, rewriterCallback) {
1280
1352
  var templateNode = getTemplateNode(template);
1281
- var rewritten = rewriterCallback(templateNode.text)
1353
+ var rewritten = rewriterCallback(templateNode.text);
1354
+
1355
+ // jquery.tmpl falls over if you use single-quotes, so replace these with a temporary marker for template rendering,
1356
+ // and then replace back after the template was rendered. This is slightly complicated by the fact that we must not interfere
1357
+ // with any code blocks - only replace apos characters outside code blocks.
1358
+ rewritten = ko.utils.stringTrim(rewritten);
1359
+ rewritten = rewritten.replace(/([\s\S]*?)(\${[\s\S]*?}|{{[\=a-z][\s\S]*?}}|$)/g, function(match) {
1360
+ // Called for each non-code-block followed by a code block (or end of template)
1361
+ var nonCodeSnippet = arguments[1];
1362
+ var codeSnippet = arguments[2];
1363
+ return nonCodeSnippet.replace(/\'/g, aposMarker) + codeSnippet;
1364
+ });
1365
+
1282
1366
  templateNode.text = rewritten;
1283
1367
  templateNode.isRewritten = true;
1284
1368
  },
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: knockoutjs-rails
3
3
  version: !ruby/object:Gem::Version
4
- version: '1.03'
4
+ version: '1.04'
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -13,7 +13,7 @@ date: 2012-01-28 00:00:00.000000000Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: railties
16
- requirement: &70266098243940 !ruby/object:Gem::Requirement
16
+ requirement: &70158057167200 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ~>
@@ -21,7 +21,7 @@ dependencies:
21
21
  version: '3.1'
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *70266098243940
24
+ version_requirements: *70158057167200
25
25
  description: Knockout is a JavaScript library that helps you to create rich, responsive
26
26
  display and editor user interfaces with a clean underlying data model
27
27
  email: