Skip to content

Commit

Permalink
Commit 65 (v1.0.0-beta.65 - Beta Candidate)
Browse files Browse the repository at this point in the history
BREAKING CHANGES AND IMPROVEMENTS

- The global namespace when JsRender is loaded without jQuery
  is now window.jsrender. (Previously it was window.jsviews).
  So when using JsRender without jQuery, you can write:
  var $ = jsrender; - and use the $ var it in the same way you
  would use the global $ when JsRender is loaded with jQuery:
  e.g. $.templates(...) or $.views.helpers(...) etc.

- AMD support has been improved and simplified. All AMD
  modules, including JsRender, with or without jQuery, now
  return the jQuery object (if loaded) or the analogous
  JsViews object.

- Node.js support and integration has been improved - along
  with improved CommonJS support, and Browserify integration.
  The file system APIs now use the syntax tmpl="./file/path.html".
  The Node.js version of jsrender.js is available as a separate
  file (available at //jsviews.com/download/jsrender-node.js).

  The Node.js version of JsRender provides the complete set of
  JsRender APIs and features, together with integration
  with NodeJS view-engines such as Express and Hapi, APIs
  for loading templates from the file system, etc.
  The file system APIs now use the syntax tmpl="./file/path.html".

  It also includes a built-in Browserify transform (see "Browserify
  Support: below).

  (Note: JsRender and JsViews will soon be published to NPM).

- The behavior when loading multiple instances of JsRender or
  JsViews files has been changed: When loading a new instance,
  the previous instance $.views, $.templates, etc. is no longer
  overwritten. So a component using JsRender or JsViews will not,
  when loaded, cause another already loaded component also using
  JsViews/JsRender to fail (except for collisions arising in the
  unlikely case where both happen to use the same
  template/converter/helper name).

  As part of this modified behavior, the noConflict support
  for JsRender had been removed.

NEW FEATURES

- observeAll() for cyclic objects is now supported for the
  vast majority of cases.
  See #304

- Improved support for data-linking to data- attributes:
  <elem data-link="data-foo{:expr}" ...>.
  After data-linking, the value of the data-foo attribute
  will be expr.toString(), but $.data(element, "foo") and
  $(element).data("foo") will actually return the value of
  expr, even if of type object.
  See #306

- Browserify Support:
  JsRender on Node.js provides a built-in Browserify
  transform - jsrender.tmplify, for including compiled JsRender
  templates from the server, as part of the client javascript
  bundle generated by Browserify.

  Usage example:

  var $jsr = require('jsrender');

  browserify(...) ... .transform($jsr.tmplify) ...
  See also http://www.jsviews.com/test/unit-tests-browserify.html

- Initial work for deployment to Bower and NPM. See
  #254
  BorisMoore/jsrender#225

Bug Fixes:

- BorisMoore/jsrender#263
  BorisMoore/jsrender#264
  Caching of template on script elements. (Unit tests
  added)

- #304
  ObserveAll on cyclic objects

- #306
  'data-xxxx' attribute using data-link

- #307
  #312
  • Loading branch information
BorisMoore committed Aug 17, 2015
1 parent 30f33ec commit 6e80da1
Show file tree
Hide file tree
Showing 33 changed files with 3,074 additions and 0 deletions.
6 changes: 6 additions & 0 deletions .gitignore
@@ -0,0 +1,6 @@
**/.*
node_modules
bower_components
test/browserify/bundles/*.js
*.config
Scripts
26 changes: 26 additions & 0 deletions gulpfile.js
@@ -0,0 +1,26 @@
var gulp = require('gulp'),
browserify = require('browserify'),
fs = require('fs');

//================================= BUNDLE - Run Browserify - create client bundles for test cases =================================//
// See https://github.com/gulpjs/gulp/blob/master/docs/recipes/browserify-with-globs.md

// Task to create Browserify client-side bundle scripts for Browserify test cases.
gulp.task('bundle', function() {
var $jsr = require('jsrender');
var gs = require('glob-stream');

return gs.create('./test/browserify/*-unit-tests.js')
.on('data', function(file) {
// file has path, base, and cwd attrs
var fileName = file.path.slice(file.base.length, -14);
browserify(file.path, {debug:true})
.transform($jsr.tmplify)
.bundle()
.pipe(fs.createWriteStream('./test/browserify/bundles/' + fileName + "-bundle.js"))
.on('error', function(err) {
// Make sure failed tests cause gulp to exit non-zero
throw err;
});
});
});
3 changes: 3 additions & 0 deletions index-node-jsr.js
@@ -0,0 +1,3 @@
(function(window, undefined) {
module.exports = require("jsrender");
})(this);
3 changes: 3 additions & 0 deletions index-node-jsv.js
@@ -0,0 +1,3 @@
(function(window, undefined) {
module.exports = require('jsviews');
})(this);
39 changes: 39 additions & 0 deletions package.json
@@ -0,0 +1,39 @@
{
"name": "jsviews",
"version": "v1.0.0-beta.65",
"description": "",
"main": "./jsviews.js",
"author": {
"name": "Boris Moore",
"url": "https://github.com/borismoore"
},
"homepage": "http://www.jsviews.com/#jsviews",
"repository": {
"type": "git",
"url": "https://github.com/borismoore/jsviews.git"
},
"license": "MIT",
"bugs": {
"url": "https://github.com/borismoore/jsviews/issues"
},
"scripts": {
"test": "node ./test/unit-tests-node-runner.js"
},
"keywords": [
"jsviews",
"jsrender",
"jquery",
"browserify",
"templates",
"template"
],
"devDependencies": {
"browserify": "^11.0.1",
"glob-stream": "^5.0.0",
"gulp": "^3.9.0",
"jquery": "^2.1.4",
"jsrender": "file:..\\jsrender",
"jsviews": "file:..\\jsviews",
"qunit": "^0.7.6"
}
}
32 changes: 32 additions & 0 deletions test/browserify/1-unit-tests.js
@@ -0,0 +1,32 @@
/*global QUnit, test, equal, ok*/
(function(undefined) {
"use strict";

QUnit.module("Browserify - client code");

test("No jQuery global: require('jsrender')()", function() {
// ............................... Hide QUnit global jQuery .................................
var jQuery = global.jQuery;
global.jQuery = undefined;

// =============================== Arrange ===============================
var data = {name: "Jo"};

// ................................ Act ..................................
var $jsr = require('jsrender')(); // Not passing in jQuery, so $jsr is jsrender namespace

// Use require to get server template, thanks to Browserify bundle that used jsrender.tmplify transform
var tmpl = require('../templates/name-template.html')($jsr); // Provide $jsr

var result = tmpl(data);

result += " " + ($jsr !== jQuery);

// ............................... Assert .................................
equal(result, "Name: Jo (name-template.html) true", "result");

// ............................... Reset .................................
global.jQuery = jQuery; // Replace QUnit global jQuery
});

})();
159 changes: 159 additions & 0 deletions test/browserify/10-errors-unit-tests.js
@@ -0,0 +1,159 @@
/*global QUnit, test, equal, ok*/
(function(undefined) {
"use strict";

QUnit.module("Browserify - client code");

test('Error cases for require() for JsRender, JsViews, JsObservable, JsRender templates', function() {
// ............................... Hide QUnit global jQuery .................................
var jQuery = global.jQuery;
global.jQuery = undefined;

var $jq, $jsr, tmpl, result;
// ................................ Act ..................................

try {
// Server template in bundle, thanks to Browserify jsrender.tmplify transform
tmpl = require('../templates/name-template.html')(); // Should provide $ with $.templates defined (jsrender or jQuery namespace)
}
catch(e) {
result = e;
}

// ............................... Assert .................................
equal(result, "Requires jsrender/jQuery", 'require("../templates/name-template.html")() throws "Requires jsrender/jQuery"');

// ................................ Act ..................................

try {
tmpl = require('../templates/name-template.html')(22); // Should provide $ with $.templates defined (jsrender or jQuery namespace)
}
catch(e) {
result = e;
}

// ............................... Assert .................................
equal(result, "Requires jsrender/jQuery", 'require("../templates/name-template.html")(22) throws "Requires jsrender/jQuery"');

// ................................ Act ..................................

$jq = require("jQuery");
try {
tmpl = require('../templates/name-template.html')($jq); // Should provide $ with $.templates defined (jsrender or jQuery namespace)
}
catch(e) {
result = e;
}

// ............................... Assert .................................
equal(result, "Requires jsrender/jQuery", 'require("../templates/name-template.html")(jq) ($ without jsrender) throws "Requires jsrender/jQuery"');

// ................................ Act ..................................

try {
$jsr = require('jsrender')({}); // Should provide null, or jQuery
}
catch(e) {
result = e;
}

// ............................... Assert .................................
equal(result, "Provide jQuery or null", 'require("jsrender")({}) throws "Provide jQuery or null"');

// ................................ Act ..................................

try {
$jsr = require('jsviews/jquery.observable')(); // Should provide jQuery

}
catch(e) {
result = e;
}

// ............................... Assert .................................
equal(result, "JsObservable requires jQuery", 'require("jquery.observable")() throws "JsObservable requires jQuery"');

// ................................ Act ..................................

try {
$jsr = require('jsviews/jquery.observable')("a"); // Should provide jQuery
}
catch(e) {
result = e;
}

// ............................... Assert .................................
equal(result, "JsObservable requires jQuery", 'require("jquery.observable")("a") throws "JsObservable requires jQuery"');

// ................................ Act ..................................

try {
$jsr = require('jsviews/jquery.views')(); // Should provide jQuery with JsRender, JsObservable

}
catch(e) {
result = e;
}

// ............................... Assert .................................
equal(result, "JsViews requires jQuery", 'require("jquery.views")() throws "JsViews requires jQuery"');

// ................................ Act ..................................

try {
$jsr = require('jsviews/jquery.views')("a"); // Should provide jQuery with JsRender, JsObservable
}
catch(e) {
result = e;
}

// ............................... Assert .................................
equal(result, "JsViews requires jQuery", 'require("jquery.views")("a") throws "JsViews requires jQuery"');

// ................................ Act ..................................

$jq = require("jQuery");

try {
$jsr = require('jsviews/jquery.views')($jq); // Should provide jQuery with JsRender, JsObservable
}
catch(e) {
result = e;
}

// ............................... Assert .................................
equal(result, "JsViews requires JsRender", 'require("jquery.views")(jQuery) throws "JsViews requires JsRender"');

// ................................ Act ..................................

$jsr = require('jsrender');

try {
$jsr = require('jsviews/jquery.views')($jsr); // Should provide jQuery with JsRender, JsObservable
}
catch(e) {
result = e;
}

// ............................... Assert .................................
equal(result, "JsViews requires jQuery", 'require("jquery.views")(jsrender) throws "JsViews requires jQuery"');

// ................................ Act ..................................

$jsr = require('jsrender')(require("jQuery"));

try {
$jsr = require('jsviews/jquery.views')($jsr); // Should provide jQuery with JsRender, JsObservable
}
catch(e) {
result = e;
}

// ............................... Assert .................................
equal(result, "JsViews requires JsObservable", 'require("jquery.views")($jsr) throws "JsViews requires JsObservable"');

// ............................... Reset .................................
global.jQuery = jQuery; // Replace QUnit global jQuery
});

})();
72 changes: 72 additions & 0 deletions test/browserify/11-errors-unit-tests.js
@@ -0,0 +1,72 @@
/*global QUnit, test, equal, ok*/
(function(undefined) {
"use strict";

QUnit.module("Browserify - client code");

test('More Errors for require() for JsRender, JsViews, JsObservable, JsRender templates', function() {
// ............................... Hide QUnit global jQuery .................................
var jQuery = global.jQuery;
global.jQuery = undefined;

var $jq, $jsr, tmpl, result;

// ................................ Act ..................................

$jsr = require("jsrender")(require("jQuery"));

try {
$jsr = require('jsviews/jquery.views')($jsr); // Should provide jQuery with JsRender, JsObservable
}
catch(e) {
result = e;
}

// ............................... Assert .................................
equal(result, "JsViews requires JsObservable", 'require("jquery.views")($jsr) throws "JsViews requires JsObservable"');

// ................................ Act ..................................

$jsr = require("jsrender")(require("jQuery"));

try {
$jsr = require('jsviews')(); // Should provide jQuery
}
catch(e) {
result = e;
}

// ............................... Assert .................................
equal(result, "JsViews requires jQuery", 'require("jsviews")($) throws "JsViews requires jQuery"');

// ................................ Act ..................................

try {
$jsr = require('jsviews')("a"); // Should provide jQuery
}
catch(e) {
result = e;
}

// ............................... Assert .................................
equal(result, "JsViews requires jQuery", 'require("jsviews")("a") throws "JsViews requires jQuery"');

// ................................ Act ..................................

$jsr = require("jsrender");

try {
$jsr = require('jsviews')($jsr); // Should provide jQuery
}
catch(e) {
result = e;
}

// ............................... Assert .................................
equal(result, "JsViews requires jQuery", 'require("jsviews")(jQuery) throws "JsViews requires jQuery"');

// ............................... Reset .................................
global.jQuery = jQuery; // Replace QUnit global jQuery
});

})();
33 changes: 33 additions & 0 deletions test/browserify/2-unit-tests.js
@@ -0,0 +1,33 @@
/*global QUnit, test, equal, ok*/
(function(undefined) {
"use strict";

QUnit.module("Browserify - client code");

test("No jQuery global: require('jsrender')($)", function() {
// ............................... Hide QUnit global jQuery .................................
var jQuery = global.jQuery;
global.jQuery = undefined;

// =============================== Arrange ===============================
var data = {name: "Jo"};

// ................................ Act ..................................
var $jq = require('jquery');
var $jsr = require('jsrender')($jq); // Provide jQuery, so $jsr === $jq is local jQuery namespace

// Use require to get server template, thanks to Browserify bundle that used jsrender.tmplify transform
var tmpl = require('../templates/name-template.html')($jsr); // Provide $jsr

var result = tmpl(data);

result += " " + ($jsr !== jQuery);

// ............................... Assert .................................
equal(result, "Name: Jo (name-template.html) true", "result");

// ............................... Reset .................................
global.jQuery = jQuery; // Replace QUnit global jQuery
});

})();

0 comments on commit 6e80da1

Please sign in to comment.