From e3f4ff223c5acd7cf97b6a9ba1cdd83111dba63b Mon Sep 17 00:00:00 2001 From: =?utf8?q?Aleksander=20=C5=81ukasz?= Date: Tue, 5 Aug 2014 10:48:07 +0200 Subject: [PATCH] wlxml: edumed - order exercise --- karma.conf.js | 1 + src/wlxml/extensions/edumed/edumed.js | 163 +++++++++++++++++++++ src/wlxml/extensions/edumed/edumed.test.js | 70 +++++++++ src/wlxml/extensions/edumed/order.xml | 5 + src/wlxml/wlxml.js | 7 +- 5 files changed, 243 insertions(+), 3 deletions(-) create mode 100644 src/wlxml/extensions/edumed/edumed.js create mode 100644 src/wlxml/extensions/edumed/edumed.test.js create mode 100644 src/wlxml/extensions/edumed/order.xml diff --git a/karma.conf.js b/karma.conf.js index 9f84f89..913c295 100644 --- a/karma.conf.js +++ b/karma.conf.js @@ -9,6 +9,7 @@ files = [ {pattern: 'libs/*.js', included: false}, {pattern: 'src/**/*.js', included: false}, {pattern: 'src/**/*.html', included: false}, + {pattern: 'src/**/*.xml', included: false}, 'tests/main.js', ]; diff --git a/src/wlxml/extensions/edumed/edumed.js b/src/wlxml/extensions/edumed/edumed.js new file mode 100644 index 0000000..3176ae0 --- /dev/null +++ b/src/wlxml/extensions/edumed/edumed.js @@ -0,0 +1,163 @@ +define(function(require) { + +'use strict'; + +var _ = require('libs/underscore'), + orderExerciseTemplate = require('libs/text!./order.xml'); + +var Item = function(node, exerciseNode) { + Object.defineProperty(this, 'text', { + get: function() { + /* globals Node */ + var firstNode = node.contents()[0]; + if(firstNode && firstNode.nodeType === Node.TEXT_NODE) { + return firstNode.getText(); + } + return ''; + } + }); + this.node = node; + this.exerciseNode = exerciseNode; +}; +_.extend(Item.prototype, { + setText: function(text) { + /* globals Node */ + var contents = this.node.contents(); + if(contents.length === 1 && contents[0].nodeType === Node.TEXT_NODE) { + contents[0].setText(text); + } else { + contents.forEach(function(childNode) { + childNode.detach(); + }); + contents.append({text: text}); + } + }, + remove: function() { + this.node.detach(); + }, + getAnswer: function() { + var toret = parseInt(this.node.getAttr('answer'), 10); + if(_.isNaN(toret)) { + toret = 1; + } + return toret; + }, + setAnswer: function(answer) { + answer = parseInt(answer, 10); + var prev = answer; + if(!_.isNumber(answer)) { + return; + } + + this.exerciseNode.object.getItems() + .sort(function(item1, item2) { + if(item1.getAnswer() > item2.getAnswer()) { + return 1; + } + return -1; + }) + .some(function(item) { + if(item.getAnswer() === prev && !item.node.sameNode(this.node)) { + item.node.setAttr('answer', prev+1); + prev = prev + 1; + } + }.bind(this)); + this.node.setAttr('answer', answer); + + } +}); + +var isItemsList = function(node) { + return node.is('list.orderable'); +}; + + +var extension = {wlxmlClass: {'exercise.order': { + methods: { + isContextRoot: function(node) { + return this.object.isItemNode(node) || this.sameNode(node); + }, + getItems: function() { + var toret = [], + exerciseNode = this; + + this.contents().some(function(node) { + if(isItemsList(node)) { + node.contents() + .filter(function(node) { + return node.is('item.answer'); + }) + .forEach(function(node) { + toret.push(new Item(node, exerciseNode)); + }); + return true; + } + }); + return toret; + }, + isItemNode: function(node) { + var list; + if(!node) { + return; + } + this.contents().some(function(node) { + if(isItemsList(node)) { + list = node; + return true; + } + }); + return list && list.sameNode(node.parent()); + }, + getDescription: function() { + var toret = []; + this.contents().some(function(node) { + if(isItemsList(node)) { + return true; + } + toret.push(node); + }); + return toret; + } + }, + transformations: { + addItem: function(text) { + var toret; + this.contents().some(function(node) { + if(isItemsList(node)) { + var itemNode = this.document.createDocumentNode({tagName: 'div', attrs: {'class': 'item.answer', answer: this.object.getItems().length+1}}); + toret = itemNode.append({text: text}); + node.append(itemNode); + return true; + } + }.bind(this)); + return toret; + }, + setDescription: function(text) { + this.contents().some(function(node) { + var textNode; + if(node.is('p')) { + textNode = node.contents()[0]; + if(!(textNode && textNode.nodeType === Node.TEXT_NODE)) { + node.prepend({text:text}); + } else { + textNode.setText(text); + } + return true; + } + }); + } + } +}}}; + +extension.document = { + methods: { + edumedCreateExerciseNode: function(klass) { + void(klass); + return this.createDocumentNode(orderExerciseTemplate); + } + } +}; + +return extension; + +}); \ No newline at end of file diff --git a/src/wlxml/extensions/edumed/edumed.test.js b/src/wlxml/extensions/edumed/edumed.test.js new file mode 100644 index 0000000..c039f0d --- /dev/null +++ b/src/wlxml/extensions/edumed/edumed.test.js @@ -0,0 +1,70 @@ +define(function(require) { + +'use strict'; +/* globals describe, it */ + +var chai = require('libs/chai'), + wlxml = require('wlxml/wlxml'); + //edumedExtension = require('./edumed.js'); + +var expect = chai.expect; + + +var getDocumentFromXML = function(xml, options) { + var doc = wlxml.WLXMLDocumentFromXML(xml, options || {}); + //doc.registerExtension(edumedExtension); + return doc; +}; + + +describe('Setting answer', function() { + it('sets answer (1)', function() { + /* jshint multistr:true */ + var doc = getDocumentFromXML('\ +
\ +
\ +
Element 3
\ +
Element 1
\ +
Element 2
\ +
\ +
'); + + doc.root.object.getItems()[2].setAnswer(1); + + var items = doc.root.object.getItems(); + + expect(items[0].getAnswer()).to.equal(3); + expect(items[1].getAnswer()).to.equal(2); + expect(items[2].getAnswer()).to.equal(1); + + }); + it('sets answer (2)', function() { + /* jshint multistr:true */ + var doc = getDocumentFromXML('\ +
\ +
\ +
Element 1
\ +
Element 2
\ +
Element 3
\ +
\ +
'); + doc.transaction(function() { + doc.root.object.getItems()[2].setAnswer(2); + }, { + error: function(e) { throw e;} + }); + + + var items = doc.root.object.getItems(); + + expect(items[0].getAnswer()).to.equal(1); + expect(items[1].getAnswer()).to.equal(3); + expect(items[2].getAnswer()).to.equal(2); + + }); +}); + + + + +}); \ No newline at end of file diff --git a/src/wlxml/extensions/edumed/order.xml b/src/wlxml/extensions/edumed/order.xml new file mode 100644 index 0000000..167e981 --- /dev/null +++ b/src/wlxml/extensions/edumed/order.xml @@ -0,0 +1,5 @@ +
+
+
+
+
\ No newline at end of file diff --git a/src/wlxml/wlxml.js b/src/wlxml/wlxml.js index 262004c..cb43f07 100644 --- a/src/wlxml/wlxml.js +++ b/src/wlxml/wlxml.js @@ -4,8 +4,9 @@ define([ 'smartxml/smartxml', 'smartxml/transformations', 'wlxml/extensions/metadata/metadata', - 'wlxml/extensions/comments/comments' -], function($, _, smartxml, transformations, metadataExtension, commentExtension) { + 'wlxml/extensions/comments/comments', + 'wlxml/extensions/edumed/edumed' +], function($, _, smartxml, transformations, metadataExtension, commentExtension, edumedExtension) { 'use strict'; @@ -184,7 +185,7 @@ $.extend(WLXMLTextNode.prototype, WLXMLDocumentNodeMethods, { var WLXMLDocument = function(xml, options) { this.classMethods = {}; this.classTransformations = {}; - smartxml.Document.call(this, xml, [metadataExtension, commentExtension]); + smartxml.Document.call(this, xml, [metadataExtension, commentExtension, edumedExtension]); this.options = options; }; -- 2.20.1