Skip to content

Commit

Permalink
Merge pull request #133 from brianjmiller/attachments
Browse files Browse the repository at this point in the history
Attachments
  • Loading branch information
brianjmiller authored Sep 26, 2016
2 parents 62730f4 + cf20663 commit 0667f93
Show file tree
Hide file tree
Showing 116 changed files with 8,926 additions and 222 deletions.
3 changes: 3 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ sudo: false
language: node_js
node_js:
- "6"
- "5"
- "4"
- "0.12"
- "0.10"
before_install: npm install -g grunt-cli
install: npm install
Expand Down
18 changes: 14 additions & 4 deletions Gruntfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@
module.exports = function(grunt) {
"use strict";
var coreFileList = [
"vendor/cryptojs-v3.0.2/rollups/sha1.js",
"vendor/cryptojs-v3.0.2/components/enc-base64.js",
"vendor/cryptojs-v3.1.2/rollups/sha1.js",
"vendor/cryptojs-v3.1.2/rollups/sha256.js",
"vendor/cryptojs-v3.1.2/components/enc-base64.js",
"vendor/cryptojs-v3.1.2/components/lib-typedarrays.js",
"src/TinCan.js",
"src/Utils.js",
"src/LRS.js",
Expand All @@ -25,15 +27,23 @@ module.exports = function(grunt) {
"src/State.js",
"src/ActivityProfile.js",
"src/AgentProfile.js",
"src/About.js"
"src/About.js",
"src/Attachment.js"
],
browserFileList = coreFileList.slice(),
nodeFileList = coreFileList.slice(),
pkg,
bower;

browserFileList.push(
"src/Environment/Browser.js"
"src/Environment/Browser.js",
// needed because IE10 doesn't support Uint8ClampedArray
// which is required by CryptoJS for typedarray support
"node_modules/js-polyfills/typedarray.js",
// needed because IE10 doesn't have ArrayBuffer slice
"node_modules/arraybuffer-slice/index.js",
// needed for IE and Safari for TextDecoder/TextEncoder
"node_modules/text-encoding/lib/encoding.js"
);
nodeFileList.push(
"src/Environment/Node.js"
Expand Down
16 changes: 15 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,5 +48,19 @@ Environments
------------

Implementing a new Environment should be straightforward and requires overloading a couple
of methods on the `TinCan.LRS` prototype. There are currently two examples, `Environment/Browser`
of methods in the library. There are currently two examples, `Environment/Browser`
and `Environment/Node`.

Attachment Support
------------------

Sending and retrieving statements with attachments via the multipart/mixed request/response
cycle works end to end with binary attachments in Node.js 4+ and in the typical modern browsers:
Chrome 53+, Firefox 48+, Safari 9+, IE 10+ (current versions at time of implementation, older versions
may work without changes but have not been tested). Attachments without included content (those using
only the `fileUrl` property) should be supported in all environments supported by the library.

Several polyfills (TypedArrays, ArrayBuffer w/ slice, Blob, TextDecoder/TextEncoder) are needed
to support various browser versions, if you are targeting a recent enough set of browsers you
can reduce the overall size of the built library by commenting out those polyfills in the
`Gruntfile.js` file and building yourself.
5 changes: 4 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,10 @@
"doc": "doc"
},
"dependencies": {
"xhr2": "0.0.7"
"xhr2": "0.0.7",
"js-polyfills": "0.1.22",
"text-encoding": "0.6.0",
"arraybuffer-slice": "0.1.2"
},
"author": "Rustici Software <[email protected]>",
"contributors": [
Expand Down
214 changes: 214 additions & 0 deletions src/Attachment.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,214 @@
/*
Copyright 2016 Rustici Software
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

/**
TinCan client library
@module TinCan
@submodule TinCan.Attachment
**/
(function () {
"use strict";

/**
@class TinCan.Attachment
@constructor
*/
var Attachment = TinCan.Attachment = function (cfg) {
this.log("constructor");

/**
@property usageType
@type String
*/
this.usageType = null;

/**
@property display
@type Object
*/
this.display = null;

/**
@property contentType
@type String
*/
this.contentType = null;

/**
@property length
@type int
*/
this.length = null;

/**
@property sha2
@type String
*/
this.sha2 = null;

/**
@property description
@type Object
*/
this.description = null;

/**
@property fileUrl
@type String
*/
this.fileUrl = null;

/**
@property content
@type ArrayBuffer
*/
this.content = null;

this.init(cfg);
};
Attachment.prototype = {
/**
@property LOG_SRC
*/
LOG_SRC: "Attachment",

/**
@method log
*/
log: TinCan.prototype.log,

/**
@method init
@param {Object} [options] Configuration used to initialize
*/
init: function (cfg) {
this.log("init");
var i,
directProps = [
"contentType",
"length",
"sha2",
"usageType",
"display",
"description",
"fileUrl"
]
;

cfg = cfg || {};

for (i = 0; i < directProps.length; i += 1) {
if (cfg.hasOwnProperty(directProps[i]) && cfg[directProps[i]] !== null) {
this[directProps[i]] = cfg[directProps[i]];
}
}

if (cfg.hasOwnProperty("content") && cfg.content !== null) {
if (typeof cfg.content === "string") {
this.setContentFromString(cfg.content);
}
else {
this.setContent(cfg.content);
}
}
},

/**
@method asVersion
@param {String} [version] Version to return (defaults to newest supported)
*/
asVersion: function (version) {
this.log("asVersion");
var result;

version = version || TinCan.versions()[0];

if (version === "0.9" || version === "0.95") {
result = null;
}
else {
result = {
contentType: this.contentType,
display: this.display,
length: this.length,
sha2: this.sha2,
usageType: this.usageType
};

if (this.fileUrl !== null) {
result.fileUrl = this.fileUrl;
}
if (this.description !== null) {
result.description = this.description;
}
}

return result;
},

/**
See {{#crossLink "TinCan.Utils/getLangDictionaryValue"}}{{/crossLink}}
@method getLangDictionaryValue
*/
getLangDictionaryValue: TinCan.Utils.getLangDictionaryValue,

/**
@method setContent
@param {ArrayBuffer} content Sets content from ArrayBuffer
*/
setContent: function (content) {
this.content = content;
this.length = content.byteLength;
this.sha2 = TinCan.Utils.getSHA256String(content);
},

/**
@method setContentFromString
@param {String} content Sets the content property of the attachment from a string
*/
setContentFromString: function (content) {
var _content = content;

_content = TinCan.Utils.stringToArrayBuffer(content);

this.setContent(_content);
},

/**
@method getContentAsString
@return {String} Value of content property as a string
*/
getContentAsString: function () {
return TinCan.Utils.stringFromArrayBuffer(this.content);
}
};

/**
@method fromJSON
@return {Object} Attachment
@static
*/
Attachment.fromJSON = function (attachmentJSON) {
Attachment.prototype.log("fromJSON");
var _attachment = JSON.parse(attachmentJSON);

return new Attachment(_attachment);
};

Attachment._defaultEncoding = "utf-8";
}());
Loading

0 comments on commit 0667f93

Please sign in to comment.