diff --git a/README.md b/README.md
index bcf27a4..49bbeb2 100644
--- a/README.md
+++ b/README.md
@@ -16,11 +16,49 @@ var ad = vast.attachAd({
id : 1
, structure : 'inline'
, sequence : 99
+ , Error: 'http://error.err'
, AdTitle : 'Common name of the ad'
, AdSystem : { name: 'Test Ad Server', version : '1.0' }
});
```
+### Ad extensions
+
+```javascript
+var VAST = require('vast-xml');
+
+var vast = new VAST();
+var ad = vast.attachAd({
+ id : 1
+ , structure : 'inline'
+ , sequence : 99
+ , Error: 'http://error.err'
+ , Extensions: ['data'] // accepts an array or string of XML, warning: XML is not validated by this library!
+ , AdTitle : 'Common name of the ad'
+ , AdSystem : { name: 'Test Ad Server', version : '1.0' }
+ });
+```
+
+### AdVerifications (VAST 4.1)
+
+```javascript
+var VAST = require('vast-xml');
+
+var vast = new VAST({version: '4.1'});
+var ad = vast.attachAd({
+ id : 'AdVerificationsExample'
+ , structure : 'wrapper'
+ , AdSystem : { name : '2.0', version : '2.0' }
+ , Error : 'https://error.url.com/path/p?error=true'
+ , AdVerifications: [{ vendor: 'thirdPartyVendor-com.omid'
+ , JavaScriptResource: { browserOptional: 'false', resourceUrl: 'https://path.to/adVerification/script.js'}
+ , trackingEvents: [{ event:'verificationNotExecuted', url: 'https://error.url.com/p?event=verificationNotExecuted?' }, {event:'secondEvent', url: 'https://second.url/p?secondEvent=true' }]
+ , VerificationParameters: 'Parameter=one&Parameter=two'
+ }]
+ , VASTAdTagURI : 'https://path.to.original/vast.xml'
+ });
+```
+
## Attach Impression tracking URLs
```javascript
@@ -133,6 +171,7 @@ vast.xml({ pretty : true, indent : ' ', newline : '\n' });
Common name of the ad
+
http://impression.com
http://sample-impression.com
diff --git a/index.js b/index.js
index 15ae052..3a894c5 100644
--- a/index.js
+++ b/index.js
@@ -16,7 +16,9 @@ var xml = function(options) {
if (ad.structure.toLowerCase() === 'wrapper') {
var wrapper = Ad.element('Wrapper');
wrapper.element('AdSystem', ad.AdSystem.name, { version : ad.AdSystem.version });
- wrapper.element('VASTAdTagURI', ad.VASTAdTagURI);
+ wrapper.element('VASTAdTagURI').cdata(ad.VASTAdTagURI);
+ if (ad.Error)
+ wrapper.element('Error').cdata(ad.Error);
ad.impressions.forEach(function(impression) {
if (track) wrapper.element('Impression').cdata(impression.url);
});
@@ -56,7 +58,8 @@ var xml = function(options) {
icon.element(r.type, r.uri, (r.creativeType) ? { creativeType : r.creativeType } : {});
});
});
- creativeType.element('Duration', c.Duration);
+ //creativeType.element('Duration', c.Duration);
+ creativeType.element('Duration').cdata(c.Duration);
var trackingEvents = creativeType.element('TrackingEvents');
c.trackingEvents.forEach(function(trackingEvent){
if (track) {
@@ -68,7 +71,7 @@ var xml = function(options) {
if (c.AdParameters) creativeType.element('AdParameters').cdata(c.AdParameters);
var videoClicks = creativeType.element('VideoClicks');
c.videoClicks.forEach(function(videoClick){
- videoClicks.element(videoClick.type, videoClick.url, { id : videoClick.id });
+ videoClicks.element('ClickThrough', videoClick.attributes).cdata(videoClick.url)
});
var mediaFiles = creativeType.element('MediaFiles');
c.mediaFiles.forEach(function(mediaFile) {
@@ -97,6 +100,41 @@ var xml = function(options) {
if (r.adParameters) companion.element('AdParameters', r.adParameters.data, { xmlEncoded : r.adParameters.xmlEncoded });
});
});
+ if (ad.Extensions) {
+ var extensions;
+ if(inline != void 0) extensions = inline.element('Extensions');
+ if(wrapper != void 0) extensions = wrapper.element('Extensions');
+ [].concat(ad.Extensions).forEach(function(extension) {
+ extensions.element('Extension', {type: 'AdVerifications'}).raw(extension);
+ });
+ }
+
+ if (ad.AdVerifications){
+ // VAST 4.1 necessary
+ var adVerifications;
+ if(wrapper != void 0) adVerifications = wrapper.element('AdVerifications');
+
+ [].concat(ad.AdVerifications).forEach(function(currentVerifiction){
+
+ var ad_verifications = adVerifications.element('Verification', {vendor: currentVerifiction.vendor});
+
+ [].concat(currentVerifiction).forEach(function(verif) {
+ // browserOptional -> true would signify that it's our native script -> e.g. to run in iOS' JSContext
+ // false meaning that the resource needs a true JS environment
+ ad_verifications.element('JavaScriptResource', {browserOptional: verif.JavaScriptResource.browserOptional}).cdata(verif.JavaScriptResource.resourceUrl);
+
+ if(verif.trackingEvents) {
+ var trackElementsNode = ad_verifications.element('TrackingEvents');
+ var currentTrackingEvent = verif.trackingEvents;
+ [].concat(currentTrackingEvent).forEach(function(currentTrackingEvent){
+ trackElementsNode.element('Tracking', {event: currentTrackingEvent.event}).cdata(currentTrackingEvent.url);
+ });
+ }
+ ad_verifications.element('VerificationParameters').cdata(verif.VerificationParameters);
+ }); // end of concat each Verification Node
+ });
+ }
+
});
return response.end(options);
};
diff --git a/lib/ad.js b/lib/ad.js
index ce65f70..ef16a1b 100644
--- a/lib/ad.js
+++ b/lib/ad.js
@@ -40,6 +40,7 @@ function Ad(settings) {
this.Error = settings.Error;
this.Description = settings.Description;
this.Advertiser = settings.Advertiser;
+ this.AdVerifications = settings.AdVerifications; // vast 4.1
this.surveys = [];
this.attachSurvey = function(settings) {
var survey = { url : settings.url }