Professional Documents
Culture Documents
/**
* mraid functionalities
**/
(function() {
if (console.oldLog === undefined) {
console.oldLog = console.log;
console.log = function(log) {
if (console.oldLog !== undefined) {
console.oldLog(log);
}
var LOG_LEVEL = {
"DEBUG" : 0,
"INFO" : 1,
"WARNING" : 2,
"ERROR" : 3
};
log.d = function(msg) {
if (logLevel <= LOG_LEVEL.DEBUG) {
console.log("[DEBUG] " + msg);
}
};
log.i = function(msg) {
if (logLevel <= LOG_LEVEL.INFO) {
console.log("[INFO] " + msg);
}
};
log.w = function(msg) {
if (logLevel <= LOG_LEVEL.WARN) {
console.log("[WARN] " + msg);
}
};
log.e = function(msg) {
console.log("[ERROR] " + msg);
};
} ());
/**
* console logger
**/
(function() {
log.i("init mraid...");
/**
* globals
**/
var mraid = window.mraid = {};
/**
* constants
**/
var VERSION = "3.0";
var orientationProperties = {
"allowOrientationChange" : true,
"forceOrientation" : DEVICE_ORIENTATIONS.NONE
};
var currentAppOrientation = {
"orientation" : DEVICE_ORIENTATIONS.NONE,
"locked" : false
};
var currentPosition = {
"x" : 0,
"y" : 0,
"width" : 0,
"height" : 0
};
var defaultPosition = {
"x" : 0,
"y" : 0,
"width" : 0,
"height" : 0
};
var expandProperties = {
"width" : 0,
"height" : 0,
"useCustomClose" : false,
"isModal" : true
};
var maxSize = {
"width" : 0,
"height" : 0
};
var screenSize = {
"width" : 0,
"height" : 0
};
var resizeProperties = {
"width" : 0,
"height" : 0,
"offsetX" : 0,
"offsetY" : 0,
"customClosePosition" : CUSTOM_CLOSE_POSITION.TOP_RIGHT,
"allowOffscreen" : true
};
var locationData = {
"lat" : 0.0,
"lon" : 0.0,
"type" : LOCATION_PROVIDER_TYPES.GPS,
"accuracy" : 0.0,
"lastfix" : 0,
"ipservice" : ""
};
var exposureProperties = {
"exposedPercentage" : 0,
"visibleRectangle" : {},
"occlusionRectangles" : null // not used in this version
};
bridge.setPlacementType = function(pt) {
placementType = pt;
};
currentPosition.x = x;
currentPosition.y = y;
currentPosition.width = width;
currentPosition.height = height;
var customClosePosition =
properties.hasOwnProperty("customClosePosition") ?
properties.customClosePosition : resizeProperties.customClosePosition;
log.d("customClosePosition " + customClosePosition);
resizeUtil.fitResizeViewOnScreen = function(properties) {
log.d("fitResizeViewOnScreen");
log.d("defaultPosition " + defaultPosition.x + " " + defaultPosition.y);
log.d("offset " + properties.offsetX + " " + properties.offsetY);
if (resizeUtil.isRectContained(maxRect, resizeRect)) {
log.d("no adjustment necessary");
return adjustments;
}
if (resizeRect.x < maxRect.x) {
adjustments.x = maxRect.x - resizeRect.x;
} else if ((resizeRect.x + resizeRect.width) > (maxRect.x + maxRect.width))
{
adjustments.x = (maxRect.x + maxRect.width) - (resizeRect.x +
resizeRect.width);
}
log.d("adjustments.x " + adjustments.x);
return adjustments;
};
this.add = function(func) {
var id = String(func);
if (!listeners[id]) {
listeners[id] = func;
this.count++;
}
};
this.remove = function(func) {
var id = String(func);
if (listeners[id]) {
listeners[id] = null;
delete listeners[id];
this.count--;
return true;
} else {
return false;
}
};
this.removeAll = function() {
for (var id in listeners) {
if (listeners.hasOwnProperty(id)) {
this.remove(listeners[id]);
}
}
};
this.broadcast = function(args) {
for (var id in listeners) {
if (listeners.hasOwnProperty(id)) {
listeners[id].apply(mraid, args);
}
}
};
this.toString = function() {
var out = [event, ':'];
for (var id in listeners) {
if (listeners.hasOwnProperty(id)) {
out.push('|', id, '|');
}
}
return out.join('');
};
};
/**
* validators
*
* The action parameter is a string which is the name of the setter function
which called this function
* (in other words, setExpandPropeties, setOrientationProperties, or
setResizeProperties).
* It serves both as the key to get the the appropriate set of validating
functions from the allValidators object
* as well as the action parameter of any error event that may be thrown.
*
* added location-data validation
**/
/**
* mraid properties
**/
mraid.supports = function(feature) {
log.i("mraid.supports: " + feature + " " + supportedFeatures[feature]);
var retval = supportedFeatures[feature];
if (typeof retval === "undefined") {
retval = false;
}
return retval;
};
mraid.getPlacementType = function() {
log.i("mraid.getPlacementType");
return placementType;
};
mraid.getOrientationProperties = function() {
log.i("mraid.getOrientationProperties");
mraid.setOrientationProperties = function(properties) {
log.i("mraid.setOrientationProperties...");
if (!validate(properties, "setOrientationProperties")) {
log.e("validation failed!");
return;
}
notifyNative("setOrientationProperties",
JSON.stringify(orientationProperties));
};
mraid.getCurrentAppOrientation = function() {
log.i("mraid.getCurrentAppOrientation");
mraid.getCurrentPosition = function() {
log.i("mraid.getCurrentPosition");
var position = {
"x": currentPosition.x,
"y": currentPosition.y,
"width": currentPosition.width,
"height": currentPosition.height
};
return position;
};
mraid.getDefaultPosition = function() {
log.i("mraid.getDefaultPosition");
var position = {
"x": defaultPosition.x,
"y": defaultPosition.y,
"width": defaultPosition.width,
"height": defaultPosition.height
};
return position;
};
mraid.getState = function() {
log.i("mraid.getState: " + state);
return state;
};
mraid.getExpandProperties = function() {
log.i("mraid.getExpandProperties");
var properties = {
"width" : expandProperties.width,
"height" : expandProperties.height,
"useCustomClose" : expandProperties.useCustomClose,
"isModal" : expandProperties.isModal
};
return properties;
};
mraid.setExpandProperties = function(properties) {
log.i("mraid.setExpandProperties");
if (!validate(properties, "setExpandProperties")) {
log.e("validation failed!");
return;
}
// In MRAID v2.0, all expanded ads by definition cover the entire screen,
// so the only property that the native side has to know about is
useCustomClose.
// (That is, the width and height properties are not needed by the native
code.)
if (expandProperties.useCustomClose !== oldUseCustomClose) {
mraid.useCustomClose(properties.useCustomClose);
}
};
mraid.getMaxSize = function() {
log.i("mraid.getMaxSize: " + maxSize.width + " x " + maxSize.height);
mraid.getScreenSize = function() {
log.i("mraid.getScreenSize: " + screenSize.width + " x " +
screenSize.height);
mraid.getResizeProperties = function() {
log.i("mraid.getResizeProperties");
var properties = {
"width" : resizeProperties.width,
"height" : resizeProperties.height,
"offsetX" : resizeProperties.offsetX,
"offsetY" : resizeProperties.offsetY,
"customClosePosition" : resizeProperties.customClosePosition,
"allowOffscreen" : resizeProperties.allowOffscreen
};
return properties;
};
mraid.setResizeProperties = function(properties) {
log.i("mraid.setResizeProperties");
isResizeReady = false;
// The properties object passed into this function must contain width,
height, offsetX, offsetY.
// The remaining two properties are optional.
var rwProps = [ "width", "height", "offsetX", "offsetY" ];
for (var i = 0; i < rwProps.length; i++) {
var propname = rwProps[i];
if (!properties.hasOwnProperty(propname)) {
var message = "required property " + propname + " is missing";
log.e(message);
broadcastEvent(EVENTS.ERROR, message, "setResizeProperties");
return;
}
}
if (!validate(properties, "setResizeProperties")) {
log.e("validation failed!");
return;
}
if (!allowOffscreen) {
if (properties.width > maxSize.width || properties.height >
maxSize.height) {
var message = "Resize width or height is greater than the maxSize
width or height!";
log.e(message);
broadcastEvent(EVENTS.ERROR, message, "setResizeProperties");
return;
}
adjustments = resizeUtil.fitResizeViewOnScreen(properties);
} else if (!resizeUtil.isCloseRegionOnScreen(properties)) {
var message = "Close event region will not appear entirely onscreen!";
log.e(message);
broadcastEvent(EVENTS.ERROR, message, "setResizeProperties");
return;
}
var params = {
"width" : resizeProperties.width,
"height" : resizeProperties.height,
"offsetX" : resizeProperties.offsetX + adjustments.x,
"offsetY" : resizeProperties.offsetY + adjustments.y,
"customClosePosition" : resizeProperties.customClosePosition,
"allowOffscreen" : resizeProperties.allowOffscreen
};
notifyNative("setResizeProperties", JSON.stringify(params));
isResizeReady = true;
};
mraid.getLocation = function() {
if (!validate(locationData, "locationData")) {
log.e("invalid location data!");
return -1;
}
var data = {
"lat" : locationData.lat,
"lon" : locationData.lon,
"type" : locationData.type,
"accuracy" : locationData.accuracy,
"lastfix" : locationData.lastfix,
"ipservice" : locationData.ipservice
};
return data;
};
/**
* mraid methods
**/
mraid.getVersion = function() {
log.i("mraid.getVersion: " + VERSION);
return VERSION;
};
if (!event || !listener) {
broadcastEvent(EVENTS.ERROR, "Both event and listener are required.",
"addEventListener");
return;
}
if (!contains(event, EVENTS)) {
broadcastEvent(EVENTS.ERROR, "Unknown MRAID event: " + event,
"addEventListener");
return;
}
if (!eventListeners[event]) {
eventListeners[event] = new EventListeners(event);
}
eventListeners[event].add(listener);
};
if (!event) {
broadcastEvent(EVENTS.ERROR, "Event is required.",
"removeEventListener");
return;
}
if (!contains(event, EVENTS)) {
broadcastEvent(EVENTS.ERROR, "Unknown MRAID event: " + event,
"removeEventListener");
return;
}
if (eventListeners[event]) {
if (!listener) {
eventListeners[event].removeAll();
} else if (!eventListeners[event].remove(listener)) {
broadcastEvent(EVENTS.ERROR, "Listener not currently registered for
event.", "removeEventListener");
}
}
mraid.open = function(url) {
log.i("mraid.open: " + url);
if (!url) {
broadcastEvent(EVENTS.ERROR, "Invalid URL: " + url, "open");
return;
}
notifyNative("open", url);
};
mraid.close = function() {
log.i("mraid.close");
if (state === STATES.HIDDEN) {
broadcastEvent(EVENTS.ERROR, "Ad cannot be closed when it is already
hidden.", "close");
return;
}
notifyNative("close");
};
mraid.unload = function() {
log.i("mraid.unload");
notifyNative("unload");
};
mraid.useCustomClose = function(shouldUseCustomClose) {
log.i("mraid.useCustomClose: " + shouldUseCustomClose);
expandProperties.useCustomClose = shouldUseCustomClose;
notifyNative("useCustomClose", shouldUseCustomClose);
};
mraid.expand = function(url) {
log.i("mraid.expand: " + (url === undefined) ? "(1-part)" : url);
mraid.isViewable = function() {
log.i("mraid.isViewable");
return isViewable;
};
mraid.playVideo = function(uri) {
log.i("mraid.playVideo: " + uri);
if (!uri) {
broadcastEvent(EVENTS.ERROR, "Invalid URI: " + uri, "playVideo");
return;
}
notifyNative("playVideo", uri);
};
mraid.resize = function() {
log.i("mraid.resize");
notifyNative("resize", JSON.stringify(resizeProperties));
};
mraid.storePicture = function(uri) {
log.i("mraid.storePicture: " + uri);
if (!mraid.supports(mraid.SUPPORTED_FEATURES.STOREPICTURE)) {
broadcastEvent(EVENTS.ERROR, "storePicture is not supported",
"storePicture");
return;
}
if (!uri) {
broadcastEvent(EVENTS.ERROR, "Invalid URI: " + uri, "storePicture");
return;
}
notifyNative("storePicture", uri);
};
mraid.createCalendarEvent = function(parameters) {
log.i("mraid.createCalendarEvent");
if (!mraid.supports(mraid.SUPPORTED_FEATURES.CALENDAR)) {
broadcastEvent(EVENTS.ERROR, "createCalendarEvent is not supported",
"createCalendarEvent");
return;
}
notifyNative("createCalendarEvent", JSON.stringify(parameters));
};
/**
* event dispatchers
**/
mraid.fireErrorEvent = function(message, action) {
broadcastEvent(EVENTS.ERROR, message, action);
};
mraid.fireReadyEvent = function() {
broadcastEvent(EVENTS.READY);
};
mraid.fireStateChangeEvent = function(newState) {
if (state !== newState) {
state = newState;
broadcastEvent(EVENTS.STATECHANGE, state);
}
};
mraid.fireViewableChangeEvent = function(newIsViewable) {
if (isViewable !== newIsViewable) {
isViewable = newIsViewable;
broadcastEvent(EVENTS.VIEWABLECHANGE, isViewable);
}
};
mraid.fireAudioVolumeChangeEvent = function(percentage) {
if (volumePercentage !== percentage) {
volumePercentage = volumePercentage;
broadcastEvent(EVENTS.AUDIOVOLUMECHANGE, percentage);
}
};
// TODO: VPAID
/**
* pokkt specific constants
**/
var NETWORK = mraid.NETWORK = {
OFFLINE :'offline',
WIFI :'wifi',
CELL :'cell',
UNKNOWN :'unknown'
};
mraid.SUPPORTED_FEATURES.AUDIO = "audio";
mraid.SUPPORTED_FEATURES.CAMERA = "camera";
mraid.SUPPORTED_FEATURES.NETWORK = "network";
mraid.SUPPORTED_FEATURES.SHAKE = "shake";
mraid.SUPPORTED_FEATURES.TILT = "tilt";
mraid.SUPPORTED_FEATURES.HEADING = "heading";
mraid.SUPPORTED_FEATURES.ORIENTATION = "orientation";
mraid.SUPPORTED_FEATURES.MAP = "map";
mraid.EVENTS.SHAKE = "shake";
mraid.EVENTS.TILTCHANGE = "tiltChange";
mraid.EVENTS.HEADINGCHANGE = "headingChange";
mraid.EVENTS.LOCATIONCHANGE = "locationChange";
mraid.EVENTS.NETWORKCHANGE = "networkChange";
mraid.EVENTS.KEYBOARDSTATECHANGE = "keyboardStateChange";
/**
* pokkt specific states
**/
var shakeProperties = {
"interval" : 0,
"intensity" : 0
};
var tiltProperties = {
"interval" : 0,
"intensity" : 0
};
var headingProperties = {
"interval" : 0,
"intensity" : 0
};
var tiltValues = {
"x" : 0,
"y" : 0,
"z" : 0
};
var headingValue = 0;
var currentNetwork = "";
var currentKeyboardState = 0;
/**
* pokkt specific validators
**/
mraidUtils.allValidators.setShakeProperties =
mraidUtils.allValidators.setTiltProperties =
mraidUtils.allValidators.setHeadingProperties = {
"intensity":function(value) { return !isNaN(value); },
"interval":function(value) { return !isNaN(value); }
};
mraidUtils.allValidators.setTilt = {
"x":function(value) { return !isNaN(value); },
"y":function(value) { return !isNaN(value); },
"z":function(value) { return !isNaN(value); }
};
/**
* pokkt's extended properties
**/
mraid.setShakeProperties = function(properties) {
log.i("mraid.setShakeProperties: " + properties);
if (!mraidUtils.validate(properties, "setShakeProperties")) {
log.e("validation failed!");
return;
}
shakeProperties = properties;
mraidBridge.notifyNative("setShakeProperties", JSON.stringify(properties));
};
mraid.getShakeProperties = function() {
log.i("mraid.getShakeProperties");
mraid.setTiltProperties = function(properties) {
log.i("mraid.setTiltProperties: " + properties);
if (!mraidUtils.validate(properties, "setTiltProperties")) {
log.e("validation failed!");
return;
}
tiltProperties = properties;
mraidBridge.notifyNative("setTiltProperties", JSON.stringify(properties));
};
mraid.getTiltProperties = function() {
log.i("mraid.getTiltProperties");
mraid.setHeadingProperties = function(properties) {
log.i("mraid.setHeadingProperties: " + properties);
if (!mraidUtils.validate(properties, "setHeadingProperties")) {
log.e("validation failed!");
return;
}
headingProperties = properties;
mraidBridge.notifyNative("setHeadingProperties",
JSON.stringify(properties));
};
mraid.getHeadingProperties = function() {
log.i("mraid.getHeadingProperties");
mraid.getTilt = function () {
log.i("mraid.getTilt");
tiltValues = newValue;
};
mraid.getNetwork = function () {
log.i("mraid.getNetwork");
return currentNetwork;
};
mraid.getHeading = function () {
log.i("mraid.getHeading");
return headingValue;
};
mraid.getKeyboardState = function () {
log.i("mraid.getKeyboardState");
return currentKeyboardState;
}
/**
* extended methods
**/
mraid.playAudio = function(url) {
log.i("mraid.playAudio " + url);
if (!mraid.supports(mraid.SUPPORTED_FEATURES.AUDIO)) {
mraidUtils.broadcastEvent(mraid.EVENTS.ERROR, "playAudio is not
supported", "playAudio");
return;
}
mraidBridge.notifyNative("playAudio", url);
};
mraid.openCamera = function () {
log.i("mraid.openCamera");
if (!mraid.supports(mraid.SUPPORTED_FEATURES.CAMERA)) {
mraidUtils.broadcastEvent(mraid.EVENTS.ERROR, "openCamera is not
supported", "openCamera");
return;
}
mraidBridge.notifyNative("openCamera");
}
/**
* event dispatchers
**/
mraid.fireShakeEvent = function() {
log.i("mraid.fireShakeEvent");
mraidUtils.broadcastEvent(mraid.EVENTS.SHAKE);
}
mraid.fireTiltChangeEvent = function(x, y, z) {
log.i("mraid.fireTiltChangeEvent, x: " + x + " y: " + y + " z: " + z);
tiltValues.x = x;
tiltValues.y = y;
tiltValues.z = z;
mraidUtils.broadcastEvent(mraid.EVENTS.TILTCHANGE, x, y, z);
}
mraid.fireHeadingChangeEvent = function(val) {
log.i("mraid.fireHeadingChangeEvent, val: " + val);
if (headingValue != val) {
headingValue = val;
mraidUtils.broadcastEvent(mraid.EVENTS.HEADINGCHANGE, val);
}
}
mraid.fireNetworkChangeEvent = function(network) {
log.d("mraid.fireNetworkChangeEvent: " + network);
if (currentNetwork != network) {
currentNetwork = network;
mraidUtils.broadcastEvent(mraid.EVENTS.NETWORKCHANGE, network);
}
}
mraid.fireKeyboardStateChangeEvent = function(state) {
log.d("mraid.fireKeyboardStateChangeEvent: " + state);
if (currentKeyboardState !== state) {
currentKeyboardState = state;
mraidUtils.broadcastEvent(mraid.EVENTS.KEYBOARDSTATECHANGE, state);
}
}
/**
* mraid functionalities
**/
(function() {
if (console.oldLog === undefined) {
console.oldLog = console.log;
console.log = function(log) {
if (console.oldLog !== undefined) {
console.oldLog(log);
}
var LOG_LEVEL = {
"DEBUG" : 0,
"INFO" : 1,
"WARNING" : 2,
"ERROR" : 3
};
log.d = function(msg) {
if (logLevel <= LOG_LEVEL.DEBUG) {
console.log("[DEBUG] " + msg);
}
};
log.i = function(msg) {
if (logLevel <= LOG_LEVEL.INFO) {
console.log("[INFO] " + msg);
}
};
log.w = function(msg) {
if (logLevel <= LOG_LEVEL.WARN) {
console.log("[WARN] " + msg);
}
};
log.e = function(msg) {
console.log("[ERROR] " + msg);
};
} ());
/**
* console logger
**/
(function() {
log.i("init mraid...");
/**
* globals
**/
var mraid = window.mraid = {};
/**
* constants
**/
var VERSION = "3.0";
/**
* states
**/
var supportedFeatures = {};
var orientationProperties = {
"allowOrientationChange" : true,
"forceOrientation" : DEVICE_ORIENTATIONS.NONE
};
var currentAppOrientation = {
"orientation" : DEVICE_ORIENTATIONS.NONE,
"locked" : false
};
var currentPosition = {
"x" : 0,
"y" : 0,
"width" : 0,
"height" : 0
};
var defaultPosition = {
"x" : 0,
"y" : 0,
"width" : 0,
"height" : 0
};
var expandProperties = {
"width" : 0,
"height" : 0,
"useCustomClose" : false,
"isModal" : true
};
var maxSize = {
"width" : 0,
"height" : 0
};
var screenSize = {
"width" : 0,
"height" : 0
};
var resizeProperties = {
"width" : 0,
"height" : 0,
"offsetX" : 0,
"offsetY" : 0,
"customClosePosition" : CUSTOM_CLOSE_POSITION.TOP_RIGHT,
"allowOffscreen" : true
};
var locationData = {
"lat" : 0.0,
"lon" : 0.0,
"type" : LOCATION_PROVIDER_TYPES.GPS,
"accuracy" : 0.0,
"lastfix" : 0,
"ipservice" : ""
};
var exposureProperties = {
"exposedPercentage" : 0,
"visibleRectangle" : {},
"occlusionRectangles" : null // not used in this version
};
bridge.setPlacementType = function(pt) {
placementType = pt;
};
currentPosition.x = x;
currentPosition.y = y;
currentPosition.width = width;
currentPosition.height = height;
var customClosePosition =
properties.hasOwnProperty("customClosePosition") ?
properties.customClosePosition : resizeProperties.customClosePosition;
log.d("customClosePosition " + customClosePosition);
resizeUtil.fitResizeViewOnScreen = function(properties) {
log.d("fitResizeViewOnScreen");
log.d("defaultPosition " + defaultPosition.x + " " + defaultPosition.y);
log.d("offset " + properties.offsetX + " " + properties.offsetY);
var resizeRect = {};
resizeRect.x = defaultPosition.x + properties.offsetX;
resizeRect.y = defaultPosition.y + properties.offsetY;
resizeRect.width = properties.width;
resizeRect.height = properties.height;
resizeUtil.printRect("resizeRect", resizeRect);
if (resizeUtil.isRectContained(maxRect, resizeRect)) {
log.d("no adjustment necessary");
return adjustments;
}
return adjustments;
};
this.add = function(func) {
var id = String(func);
if (!listeners[id]) {
listeners[id] = func;
this.count++;
}
};
this.remove = function(func) {
var id = String(func);
if (listeners[id]) {
listeners[id] = null;
delete listeners[id];
this.count--;
return true;
} else {
return false;
}
};
this.removeAll = function() {
for (var id in listeners) {
if (listeners.hasOwnProperty(id)) {
this.remove(listeners[id]);
}
}
};
this.broadcast = function(args) {
for (var id in listeners) {
if (listeners.hasOwnProperty(id)) {
listeners[id].apply(mraid, args);
}
}
};
this.toString = function() {
var out = [event, ':'];
for (var id in listeners) {
if (listeners.hasOwnProperty(id)) {
out.push('|', id, '|');
}
}
return out.join('');
};
};
/**
* validators
*
* The action parameter is a string which is the name of the setter function
which called this function
* (in other words, setExpandPropeties, setOrientationProperties, or
setResizeProperties).
* It serves both as the key to get the the appropriate set of validating
functions from the allValidators object
* as well as the action parameter of any error event that may be thrown.
*
* added location-data validation
**/
/**
* mraid properties
**/
mraid.supports = function(feature) {
log.i("mraid.supports: " + feature + " " + supportedFeatures[feature]);
var retval = supportedFeatures[feature];
if (typeof retval === "undefined") {
retval = false;
}
return retval;
};
mraid.getPlacementType = function() {
log.i("mraid.getPlacementType");
return placementType;
};
mraid.getOrientationProperties = function() {
log.i("mraid.getOrientationProperties");
mraid.setOrientationProperties = function(properties) {
log.i("mraid.setOrientationProperties...");
if (!validate(properties, "setOrientationProperties")) {
log.e("validation failed!");
return;
}
orientationProperties.allowOrientationChange =
newOrientationProperties.allowOrientationChange;
orientationProperties.forceOrientation =
newOrientationProperties.forceOrientation;
notifyNative("setOrientationProperties",
JSON.stringify(orientationProperties));
};
mraid.getCurrentAppOrientation = function() {
log.i("mraid.getCurrentAppOrientation");
mraid.getCurrentPosition = function() {
log.i("mraid.getCurrentPosition");
var position = {
"x": currentPosition.x,
"y": currentPosition.y,
"width": currentPosition.width,
"height": currentPosition.height
};
return position;
};
mraid.getDefaultPosition = function() {
log.i("mraid.getDefaultPosition");
var position = {
"x": defaultPosition.x,
"y": defaultPosition.y,
"width": defaultPosition.width,
"height": defaultPosition.height
};
return position;
};
mraid.getState = function() {
log.i("mraid.getState: " + state);
return state;
};
mraid.getExpandProperties = function() {
log.i("mraid.getExpandProperties");
var properties = {
"width" : expandProperties.width,
"height" : expandProperties.height,
"useCustomClose" : expandProperties.useCustomClose,
"isModal" : expandProperties.isModal
};
return properties;
};
mraid.setExpandProperties = function(properties) {
log.i("mraid.setExpandProperties");
if (!validate(properties, "setExpandProperties")) {
log.e("validation failed!");
return;
}
// In MRAID v2.0, all expanded ads by definition cover the entire screen,
// so the only property that the native side has to know about is
useCustomClose.
// (That is, the width and height properties are not needed by the native
code.)
if (expandProperties.useCustomClose !== oldUseCustomClose) {
mraid.useCustomClose(properties.useCustomClose);
}
};
mraid.getMaxSize = function() {
log.i("mraid.getMaxSize: " + maxSize.width + " x " + maxSize.height);
mraid.getScreenSize = function() {
log.i("mraid.getScreenSize: " + screenSize.width + " x " +
screenSize.height);
mraid.getResizeProperties = function() {
log.i("mraid.getResizeProperties");
var properties = {
"width" : resizeProperties.width,
"height" : resizeProperties.height,
"offsetX" : resizeProperties.offsetX,
"offsetY" : resizeProperties.offsetY,
"customClosePosition" : resizeProperties.customClosePosition,
"allowOffscreen" : resizeProperties.allowOffscreen
};
return properties;
};
mraid.setResizeProperties = function(properties) {
log.i("mraid.setResizeProperties");
isResizeReady = false;
// The properties object passed into this function must contain width,
height, offsetX, offsetY.
// The remaining two properties are optional.
var rwProps = [ "width", "height", "offsetX", "offsetY" ];
for (var i = 0; i < rwProps.length; i++) {
var propname = rwProps[i];
if (!properties.hasOwnProperty(propname)) {
var message = "required property " + propname + " is missing";
log.e(message);
broadcastEvent(EVENTS.ERROR, message, "setResizeProperties");
return;
}
}
if (!validate(properties, "setResizeProperties")) {
log.e("validation failed!");
return;
}
if (!allowOffscreen) {
if (properties.width > maxSize.width || properties.height >
maxSize.height) {
var message = "Resize width or height is greater than the maxSize
width or height!";
log.e(message);
broadcastEvent(EVENTS.ERROR, message, "setResizeProperties");
return;
}
adjustments = resizeUtil.fitResizeViewOnScreen(properties);
} else if (!resizeUtil.isCloseRegionOnScreen(properties)) {
var message = "Close event region will not appear entirely onscreen!";
log.e(message);
broadcastEvent(EVENTS.ERROR, message, "setResizeProperties");
return;
}
var params = {
"width" : resizeProperties.width,
"height" : resizeProperties.height,
"offsetX" : resizeProperties.offsetX + adjustments.x,
"offsetY" : resizeProperties.offsetY + adjustments.y,
"customClosePosition" : resizeProperties.customClosePosition,
"allowOffscreen" : resizeProperties.allowOffscreen
};
notifyNative("setResizeProperties", JSON.stringify(params));
isResizeReady = true;
};
mraid.getLocation = function() {
if (!validate(locationData, "locationData")) {
log.e("invalid location data!");
return -1;
}
var data = {
"lat" : locationData.lat,
"lon" : locationData.lon,
"type" : locationData.type,
"accuracy" : locationData.accuracy,
"lastfix" : locationData.lastfix,
"ipservice" : locationData.ipservice
};
return data;
};
/**
* mraid methods
**/
mraid.getVersion = function() {
log.i("mraid.getVersion: " + VERSION);
return VERSION;
};
if (!event || !listener) {
broadcastEvent(EVENTS.ERROR, "Both event and listener are required.",
"addEventListener");
return;
}
if (!contains(event, EVENTS)) {
broadcastEvent(EVENTS.ERROR, "Unknown MRAID event: " + event,
"addEventListener");
return;
}
if (!eventListeners[event]) {
eventListeners[event] = new EventListeners(event);
}
eventListeners[event].add(listener);
};
if (!event) {
broadcastEvent(EVENTS.ERROR, "Event is required.",
"removeEventListener");
return;
}
if (!contains(event, EVENTS)) {
broadcastEvent(EVENTS.ERROR, "Unknown MRAID event: " + event,
"removeEventListener");
return;
}
if (eventListeners[event]) {
if (!listener) {
eventListeners[event].removeAll();
} else if (!eventListeners[event].remove(listener)) {
broadcastEvent(EVENTS.ERROR, "Listener not currently registered for
event.", "removeEventListener");
}
}
mraid.open = function(url) {
log.i("mraid.open: " + url);
if (!url) {
broadcastEvent(EVENTS.ERROR, "Invalid URL: " + url, "open");
return;
}
notifyNative("open", url);
};
mraid.close = function() {
log.i("mraid.close");
notifyNative("close");
};
mraid.unload = function() {
log.i("mraid.unload");
notifyNative("unload");
};
mraid.useCustomClose = function(shouldUseCustomClose) {
log.i("mraid.useCustomClose: " + shouldUseCustomClose);
expandProperties.useCustomClose = shouldUseCustomClose;
notifyNative("useCustomClose", shouldUseCustomClose);
};
mraid.expand = function(url) {
log.i("mraid.expand: " + (url === undefined) ? "(1-part)" : url);
mraid.isViewable = function() {
log.i("mraid.isViewable");
return isViewable;
};
mraid.playVideo = function(uri) {
log.i("mraid.playVideo: " + uri);
if (!uri) {
broadcastEvent(EVENTS.ERROR, "Invalid URI: " + uri, "playVideo");
return;
}
notifyNative("playVideo", uri);
};
mraid.resize = function() {
log.i("mraid.resize");
notifyNative("resize", JSON.stringify(resizeProperties));
};
mraid.storePicture = function(uri) {
log.i("mraid.storePicture: " + uri);
if (!mraid.supports(mraid.SUPPORTED_FEATURES.STOREPICTURE)) {
broadcastEvent(EVENTS.ERROR, "storePicture is not supported",
"storePicture");
return;
}
notifyNative("storePicture", uri);
};
mraid.createCalendarEvent = function(parameters) {
log.i("mraid.createCalendarEvent");
if (!mraid.supports(mraid.SUPPORTED_FEATURES.CALENDAR)) {
broadcastEvent(EVENTS.ERROR, "createCalendarEvent is not supported",
"createCalendarEvent");
return;
}
notifyNative("createCalendarEvent", JSON.stringify(parameters));
};
/**
* event dispatchers
**/
mraid.fireErrorEvent = function(message, action) {
broadcastEvent(EVENTS.ERROR, message, action);
};
mraid.fireReadyEvent = function() {
broadcastEvent(EVENTS.READY);
};
mraid.fireStateChangeEvent = function(newState) {
if (state !== newState) {
state = newState;
broadcastEvent(EVENTS.STATECHANGE, state);
}
};
mraid.fireViewableChangeEvent = function(newIsViewable) {
if (isViewable !== newIsViewable) {
isViewable = newIsViewable;
broadcastEvent(EVENTS.VIEWABLECHANGE, isViewable);
}
};
mraid.fireAudioVolumeChangeEvent = function(percentage) {
if (volumePercentage !== percentage) {
volumePercentage = volumePercentage;
broadcastEvent(EVENTS.AUDIOVOLUMECHANGE, percentage);
}
};
// TODO: VPAID
/**
* pokkt extended featuers
**/
(function() {
log.i("setting up: mraid-extensions...");
/**
* pokkt specific constants
**/
var NETWORK = mraid.NETWORK = {
OFFLINE :'offline',
WIFI :'wifi',
CELL :'cell',
UNKNOWN :'unknown'
};
mraid.SUPPORTED_FEATURES.AUDIO = "audio";
mraid.SUPPORTED_FEATURES.CAMERA = "camera";
mraid.SUPPORTED_FEATURES.NETWORK = "network";
mraid.SUPPORTED_FEATURES.SHAKE = "shake";
mraid.SUPPORTED_FEATURES.TILT = "tilt";
mraid.SUPPORTED_FEATURES.HEADING = "heading";
mraid.SUPPORTED_FEATURES.ORIENTATION = "orientation";
mraid.SUPPORTED_FEATURES.MAP = "map";
mraid.EVENTS.SHAKE = "shake";
mraid.EVENTS.TILTCHANGE = "tiltChange";
mraid.EVENTS.HEADINGCHANGE = "headingChange";
mraid.EVENTS.LOCATIONCHANGE = "locationChange";
mraid.EVENTS.NETWORKCHANGE = "networkChange";
mraid.EVENTS.KEYBOARDSTATECHANGE = "keyboardStateChange";
/**
* pokkt specific states
**/
var shakeProperties = {
"interval" : 0,
"intensity" : 0
};
var tiltProperties = {
"interval" : 0,
"intensity" : 0
};
var headingProperties = {
"interval" : 0,
"intensity" : 0
};
var tiltValues = {
"x" : 0,
"y" : 0,
"z" : 0
};
var headingValue = 0;
var currentNetwork = "";
var currentKeyboardState = 0;
/**
* pokkt specific validators
**/
mraidUtils.allValidators.setShakeProperties =
mraidUtils.allValidators.setTiltProperties =
mraidUtils.allValidators.setHeadingProperties = {
"intensity":function(value) { return !isNaN(value); },
"interval":function(value) { return !isNaN(value); }
};
mraidUtils.allValidators.setTilt = {
"x":function(value) { return !isNaN(value); },
"y":function(value) { return !isNaN(value); },
"z":function(value) { return !isNaN(value); }
};
/**
* pokkt's extended properties
**/
mraid.setShakeProperties = function(properties) {
log.i("mraid.setShakeProperties: " + properties);
if (!mraidUtils.validate(properties, "setShakeProperties")) {
log.e("validation failed!");
return;
}
shakeProperties = properties;
mraidBridge.notifyNative("setShakeProperties", JSON.stringify(properties));
};
mraid.getShakeProperties = function() {
log.i("mraid.getShakeProperties");
mraid.setTiltProperties = function(properties) {
log.i("mraid.setTiltProperties: " + properties);
if (!mraidUtils.validate(properties, "setTiltProperties")) {
log.e("validation failed!");
return;
}
tiltProperties = properties;
mraidBridge.notifyNative("setTiltProperties", JSON.stringify(properties));
};
mraid.getTiltProperties = function() {
log.i("mraid.getTiltProperties");
mraid.setHeadingProperties = function(properties) {
log.i("mraid.setHeadingProperties: " + properties);
if (!mraidUtils.validate(properties, "setHeadingProperties")) {
log.e("validation failed!");
return;
}
headingProperties = properties;
mraidBridge.notifyNative("setHeadingProperties",
JSON.stringify(properties));
};
mraid.getHeadingProperties = function() {
log.i("mraid.getHeadingProperties");
mraid.getTilt = function () {
log.i("mraid.getTilt");
tiltValues = newValue;
};
mraid.getNetwork = function () {
log.i("mraid.getNetwork");
return currentNetwork;
};
mraid.getHeading = function () {
log.i("mraid.getHeading");
return headingValue;
};
mraid.getKeyboardState = function () {
log.i("mraid.getKeyboardState");
return currentKeyboardState;
}
/**
* extended methods
**/
mraid.playAudio = function(url) {
log.i("mraid.playAudio " + url);
if (!mraid.supports(mraid.SUPPORTED_FEATURES.AUDIO)) {
mraidUtils.broadcastEvent(mraid.EVENTS.ERROR, "playAudio is not
supported", "playAudio");
return;
}
mraidBridge.notifyNative("playAudio", url);
};
mraid.openCamera = function () {
log.i("mraid.openCamera");
if (!mraid.supports(mraid.SUPPORTED_FEATURES.CAMERA)) {
mraidUtils.broadcastEvent(mraid.EVENTS.ERROR, "openCamera is not
supported", "openCamera");
return;
}
mraidBridge.notifyNative("openCamera");
}
/**
* event dispatchers
**/
mraid.fireShakeEvent = function() {
log.i("mraid.fireShakeEvent");
mraidUtils.broadcastEvent(mraid.EVENTS.SHAKE);
}
mraid.fireTiltChangeEvent = function(x, y, z) {
log.i("mraid.fireTiltChangeEvent, x: " + x + " y: " + y + " z: " + z);
tiltValues.x = x;
tiltValues.y = y;
tiltValues.z = z;
mraidUtils.broadcastEvent(mraid.EVENTS.TILTCHANGE, x, y, z);
}
mraid.fireHeadingChangeEvent = function(val) {
log.i("mraid.fireHeadingChangeEvent, val: " + val);
if (headingValue != val) {
headingValue = val;
mraidUtils.broadcastEvent(mraid.EVENTS.HEADINGCHANGE, val);
}
}
mraid.fireNetworkChangeEvent = function(network) {
log.d("mraid.fireNetworkChangeEvent: " + network);
if (currentNetwork != network) {
currentNetwork = network;
mraidUtils.broadcastEvent(mraid.EVENTS.NETWORKCHANGE, network);
}
}
mraid.fireKeyboardStateChangeEvent = function(state) {
log.d("mraid.fireKeyboardStateChangeEvent: " + state);
if (currentKeyboardState !== state) {
currentKeyboardState = state;
mraidUtils.broadcastEvent(mraid.EVENTS.KEYBOARDSTATECHANGE, state);
}
}
/**
* mraid functionalities
**/
(function() {
if (console.oldLog === undefined) {
console.oldLog = console.log;
console.log = function(log) {
if (console.oldLog !== undefined) {
console.oldLog(log);
}
var LOG_LEVEL = {
"DEBUG" : 0,
"INFO" : 1,
"WARNING" : 2,
"ERROR" : 3
};
log.d = function(msg) {
if (logLevel <= LOG_LEVEL.DEBUG) {
console.log("[DEBUG] " + msg);
}
};
log.i = function(msg) {
if (logLevel <= LOG_LEVEL.INFO) {
console.log("[INFO] " + msg);
}
};
log.w = function(msg) {
if (logLevel <= LOG_LEVEL.WARN) {
console.log("[WARN] " + msg);
}
};
log.e = function(msg) {
console.log("[ERROR] " + msg);
};
} ());
/**
* console logger
**/
(function() {
log.i("init mraid...");
/**
* globals
**/
var mraid = window.mraid = {};
/**
* states
**/
var supportedFeatures = {};
var orientationProperties = {
"allowOrientationChange" : true,
"forceOrientation" : DEVICE_ORIENTATIONS.NONE
};
var currentAppOrientation = {
"orientation" : DEVICE_ORIENTATIONS.NONE,
"locked" : false
};
var currentPosition = {
"x" : 0,
"y" : 0,
"width" : 0,
"height" : 0
};
var defaultPosition = {
"x" : 0,
"y" : 0,
"width" : 0,
"height" : 0
};
var expandProperties = {
"width" : 0,
"height" : 0,
"useCustomClose" : false,
"isModal" : true
};
var maxSize = {
"width" : 0,
"height" : 0
};
var screenSize = {
"width" : 0,
"height" : 0
};
var resizeProperties = {
"width" : 0,
"height" : 0,
"offsetX" : 0,
"offsetY" : 0,
"customClosePosition" : CUSTOM_CLOSE_POSITION.TOP_RIGHT,
"allowOffscreen" : true
};
var locationData = {
"lat" : 0.0,
"lon" : 0.0,
"type" : LOCATION_PROVIDER_TYPES.GPS,
"accuracy" : 0.0,
"lastfix" : 0,
"ipservice" : ""
};
var exposureProperties = {
"exposedPercentage" : 0,
"visibleRectangle" : {},
"occlusionRectangles" : null // not used in this version
};
bridge.setPlacementType = function(pt) {
placementType = pt;
};
var customClosePosition =
properties.hasOwnProperty("customClosePosition") ?
properties.customClosePosition : resizeProperties.customClosePosition;
log.d("customClosePosition " + customClosePosition);
resizeUtil.fitResizeViewOnScreen = function(properties) {
log.d("fitResizeViewOnScreen");
log.d("defaultPosition " + defaultPosition.x + " " + defaultPosition.y);
log.d("offset " + properties.offsetX + " " + properties.offsetY);
if (resizeUtil.isRectContained(maxRect, resizeRect)) {
log.d("no adjustment necessary");
return adjustments;
}
return adjustments;
};
this.add = function(func) {
var id = String(func);
if (!listeners[id]) {
listeners[id] = func;
this.count++;
}
};
this.remove = function(func) {
var id = String(func);
if (listeners[id]) {
listeners[id] = null;
delete listeners[id];
this.count--;
return true;
} else {
return false;
}
};
this.removeAll = function() {
for (var id in listeners) {
if (listeners.hasOwnProperty(id)) {
this.remove(listeners[id]);
}
}
};
this.broadcast = function(args) {
for (var id in listeners) {
if (listeners.hasOwnProperty(id)) {
listeners[id].apply(mraid, args);
}
}
};
this.toString = function() {
var out = [event, ':'];
for (var id in listeners) {
if (listeners.hasOwnProperty(id)) {
out.push('|', id, '|');
}
}
return out.join('');
};
};
/**
* validators
*
* The action parameter is a string which is the name of the setter function
which called this function
* (in other words, setExpandPropeties, setOrientationProperties, or
setResizeProperties).
* It serves both as the key to get the the appropriate set of validating
functions from the allValidators object
* as well as the action parameter of any error event that may be thrown.
*
* added location-data validation
**/
/**
* mraid properties
**/
mraid.supports = function(feature) {
log.i("mraid.supports: " + feature + " " + supportedFeatures[feature]);
var retval = supportedFeatures[feature];
if (typeof retval === "undefined") {
retval = false;
}
return retval;
};
mraid.getPlacementType = function() {
log.i("mraid.getPlacementType");
return placementType;
};
mraid.getOrientationProperties = function() {
log.i("mraid.getOrientationProperties");
mraid.setOrientationProperties = function(properties) {
log.i("mraid.setOrientationProperties...");
if (!validate(properties, "setOrientationProperties")) {
log.e("validation failed!");
return;
}
orientationProperties.allowOrientationChange =
newOrientationProperties.allowOrientationChange;
orientationProperties.forceOrientation =
newOrientationProperties.forceOrientation;
notifyNative("setOrientationProperties",
JSON.stringify(orientationProperties));
};
mraid.getCurrentAppOrientation = function() {
log.i("mraid.getCurrentAppOrientation");
mraid.getCurrentPosition = function() {
log.i("mraid.getCurrentPosition");
var position = {
"x": currentPosition.x,
"y": currentPosition.y,
"width": currentPosition.width,
"height": currentPosition.height
};
return position;
};
mraid.getDefaultPosition = function() {
log.i("mraid.getDefaultPosition");
var position = {
"x": defaultPosition.x,
"y": defaultPosition.y,
"width": defaultPosition.width,
"height": defaultPosition.height
};
return position;
};
mraid.getState = function() {
log.i("mraid.getState: " + state);
return state;
};
mraid.getExpandProperties = function() {
log.i("mraid.getExpandProperties");
var properties = {
"width" : expandProperties.width,
"height" : expandProperties.height,
"useCustomClose" : expandProperties.useCustomClose,
"isModal" : expandProperties.isModal
};
return properties;
};
mraid.setExpandProperties = function(properties) {
log.i("mraid.setExpandProperties");
if (!validate(properties, "setExpandProperties")) {
log.e("validation failed!");
return;
}
// In MRAID v2.0, all expanded ads by definition cover the entire screen,
// so the only property that the native side has to know about is
useCustomClose.
// (That is, the width and height properties are not needed by the native
code.)
if (expandProperties.useCustomClose !== oldUseCustomClose) {
mraid.useCustomClose(properties.useCustomClose);
}
};
mraid.getMaxSize = function() {
log.i("mraid.getMaxSize: " + maxSize.width + " x " + maxSize.height);
mraid.getScreenSize = function() {
log.i("mraid.getScreenSize: " + screenSize.width + " x " +
screenSize.height);
mraid.getResizeProperties = function() {
log.i("mraid.getResizeProperties");
var properties = {
"width" : resizeProperties.width,
"height" : resizeProperties.height,
"offsetX" : resizeProperties.offsetX,
"offsetY" : resizeProperties.offsetY,
"customClosePosition" : resizeProperties.customClosePosition,
"allowOffscreen" : resizeProperties.allowOffscreen
};
return properties;
};
mraid.setResizeProperties = function(properties) {
log.i("mraid.setResizeProperties");
isResizeReady = false;
// The properties object passed into this function must contain width,
height, offsetX, offsetY.
// The remaining two properties are optional.
var rwProps = [ "width", "height", "offsetX", "offsetY" ];
for (var i = 0; i < rwProps.length; i++) {
var propname = rwProps[i];
if (!properties.hasOwnProperty(propname)) {
var message = "required property " + propname + " is missing";
log.e(message);
broadcastEvent(EVENTS.ERROR, message, "setResizeProperties");
return;
}
}
if (!validate(properties, "setResizeProperties")) {
log.e("validation failed!");
return;
}
if (!allowOffscreen) {
if (properties.width > maxSize.width || properties.height >
maxSize.height) {
var message = "Resize width or height is greater than the maxSize
width or height!";
log.e(message);
broadcastEvent(EVENTS.ERROR, message, "setResizeProperties");
return;
}
adjustments = resizeUtil.fitResizeViewOnScreen(properties);
} else if (!resizeUtil.isCloseRegionOnScreen(properties)) {
var message = "Close event region will not appear entirely onscreen!";
log.e(message);
broadcastEvent(EVENTS.ERROR, message, "setResizeProperties");
return;
}
var params = {
"width" : resizeProperties.width,
"height" : resizeProperties.height,
"offsetX" : resizeProperties.offsetX + adjustments.x,
"offsetY" : resizeProperties.offsetY + adjustments.y,
"customClosePosition" : resizeProperties.customClosePosition,
"allowOffscreen" : resizeProperties.allowOffscreen
};
notifyNative("setResizeProperties", JSON.stringify(params));
isResizeReady = true;
};
mraid.getLocation = function() {
if (!validate(locationData, "locationData")) {
log.e("invalid location data!");
return -1;
}
var data = {
"lat" : locationData.lat,
"lon" : locationData.lon,
"type" : locationData.type,
"accuracy" : locationData.accuracy,
"lastfix" : locationData.lastfix,
"ipservice" : locationData.ipservice
};
return data;
};
/**
* mraid methods
**/
mraid.getVersion = function() {
log.i("mraid.getVersion: " + VERSION);
return VERSION;
};
if (!contains(event, EVENTS)) {
broadcastEvent(EVENTS.ERROR, "Unknown MRAID event: " + event,
"addEventListener");
return;
}
if (!eventListeners[event]) {
eventListeners[event] = new EventListeners(event);
}
eventListeners[event].add(listener);
};
if (!event) {
broadcastEvent(EVENTS.ERROR, "Event is required.",
"removeEventListener");
return;
}
if (!contains(event, EVENTS)) {
broadcastEvent(EVENTS.ERROR, "Unknown MRAID event: " + event,
"removeEventListener");
return;
}
if (eventListeners[event]) {
if (!listener) {
eventListeners[event].removeAll();
} else if (!eventListeners[event].remove(listener)) {
broadcastEvent(EVENTS.ERROR, "Listener not currently registered for
event.", "removeEventListener");
}
}
mraid.open = function(url) {
log.i("mraid.open: " + url);
if (!url) {
broadcastEvent(EVENTS.ERROR, "Invalid URL: " + url, "open");
return;
}
notifyNative("open", url);
};
mraid.close = function() {
log.i("mraid.close");
notifyNative("close");
};
mraid.unload = function() {
log.i("mraid.unload");
notifyNative("unload");
};
mraid.useCustomClose = function(shouldUseCustomClose) {
log.i("mraid.useCustomClose: " + shouldUseCustomClose);
expandProperties.useCustomClose = shouldUseCustomClose;
notifyNative("useCustomClose", shouldUseCustomClose);
};
mraid.expand = function(url) {
log.i("mraid.expand: " + (url === undefined) ? "(1-part)" : url);
mraid.isViewable = function() {
log.i("mraid.isViewable");
return isViewable;
};
mraid.playVideo = function(uri) {
log.i("mraid.playVideo: " + uri);
if (!uri) {
broadcastEvent(EVENTS.ERROR, "Invalid URI: " + uri, "playVideo");
return;
}
notifyNative("playVideo", uri);
};
mraid.resize = function() {
log.i("mraid.resize");
notifyNative("resize", JSON.stringify(resizeProperties));
};
mraid.storePicture = function(uri) {
log.i("mraid.storePicture: " + uri);
if (!mraid.supports(mraid.SUPPORTED_FEATURES.STOREPICTURE)) {
broadcastEvent(EVENTS.ERROR, "storePicture is not supported",
"storePicture");
return;
}
if (!uri) {
broadcastEvent(EVENTS.ERROR, "Invalid URI: " + uri, "storePicture");
return;
}
notifyNative("storePicture", uri);
};
mraid.createCalendarEvent = function(parameters) {
log.i("mraid.createCalendarEvent");
if (!mraid.supports(mraid.SUPPORTED_FEATURES.CALENDAR)) {
broadcastEvent(EVENTS.ERROR, "createCalendarEvent is not supported",
"createCalendarEvent");
return;
}
notifyNative("createCalendarEvent", JSON.stringify(parameters));
};
/**
* event dispatchers
**/
mraid.fireErrorEvent = function(message, action) {
broadcastEvent(EVENTS.ERROR, message, action);
};
mraid.fireReadyEvent = function() {
broadcastEvent(EVENTS.READY);
};
mraid.fireStateChangeEvent = function(newState) {
if (state !== newState) {
state = newState;
broadcastEvent(EVENTS.STATECHANGE, state);
}
};
mraid.fireViewableChangeEvent = function(newIsViewable) {
if (isViewable !== newIsViewable) {
isViewable = newIsViewable;
broadcastEvent(EVENTS.VIEWABLECHANGE, isViewable);
}
};
mraid.fireAudioVolumeChangeEvent = function(percentage) {
if (volumePercentage !== percentage) {
volumePercentage = volumePercentage;
broadcastEvent(EVENTS.AUDIOVOLUMECHANGE, percentage);
}
};
// TODO: VPAID
/**
* pokkt specific constants
**/
var NETWORK = mraid.NETWORK = {
OFFLINE :'offline',
WIFI :'wifi',
CELL :'cell',
UNKNOWN :'unknown'
};
mraid.SUPPORTED_FEATURES.AUDIO = "audio";
mraid.SUPPORTED_FEATURES.CAMERA = "camera";
mraid.SUPPORTED_FEATURES.NETWORK = "network";
mraid.SUPPORTED_FEATURES.SHAKE = "shake";
mraid.SUPPORTED_FEATURES.TILT = "tilt";
mraid.SUPPORTED_FEATURES.HEADING = "heading";
mraid.SUPPORTED_FEATURES.ORIENTATION = "orientation";
mraid.SUPPORTED_FEATURES.MAP = "map";
mraid.EVENTS.SHAKE = "shake";
mraid.EVENTS.TILTCHANGE = "tiltChange";
mraid.EVENTS.HEADINGCHANGE = "headingChange";
mraid.EVENTS.LOCATIONCHANGE = "locationChange";
mraid.EVENTS.NETWORKCHANGE = "networkChange";
mraid.EVENTS.KEYBOARDSTATECHANGE = "keyboardStateChange";
/**
* pokkt specific states
**/
var shakeProperties = {
"interval" : 0,
"intensity" : 0
};
var tiltProperties = {
"interval" : 0,
"intensity" : 0
};
var headingProperties = {
"interval" : 0,
"intensity" : 0
};
var tiltValues = {
"x" : 0,
"y" : 0,
"z" : 0
};
var headingValue = 0;
var currentNetwork = "";
var currentKeyboardState = 0;
/**
* pokkt specific validators
**/
mraidUtils.allValidators.setShakeProperties =
mraidUtils.allValidators.setTiltProperties =
mraidUtils.allValidators.setHeadingProperties = {
"intensity":function(value) { return !isNaN(value); },
"interval":function(value) { return !isNaN(value); }
};
mraidUtils.allValidators.setTilt = {
"x":function(value) { return !isNaN(value); },
"y":function(value) { return !isNaN(value); },
"z":function(value) { return !isNaN(value); }
};
/**
* pokkt's extended properties
**/
mraid.setShakeProperties = function(properties) {
log.i("mraid.setShakeProperties: " + properties);
if (!mraidUtils.validate(properties, "setShakeProperties")) {
log.e("validation failed!");
return;
}
shakeProperties = properties;
mraidBridge.notifyNative("setShakeProperties", JSON.stringify(properties));
};
mraid.getShakeProperties = function() {
log.i("mraid.getShakeProperties");
mraid.setTiltProperties = function(properties) {
log.i("mraid.setTiltProperties: " + properties);
if (!mraidUtils.validate(properties, "setTiltProperties")) {
log.e("validation failed!");
return;
}
tiltProperties = properties;
mraidBridge.notifyNative("setTiltProperties", JSON.stringify(properties));
};
mraid.getTiltProperties = function() {
log.i("mraid.getTiltProperties");
mraid.setHeadingProperties = function(properties) {
log.i("mraid.setHeadingProperties: " + properties);
if (!mraidUtils.validate(properties, "setHeadingProperties")) {
log.e("validation failed!");
return;
}
headingProperties = properties;
mraidBridge.notifyNative("setHeadingProperties",
JSON.stringify(properties));
};
mraid.getHeadingProperties = function() {
log.i("mraid.getHeadingProperties");
mraid.getTilt = function () {
log.i("mraid.getTilt");
tiltValues = newValue;
};
mraid.getNetwork = function () {
log.i("mraid.getNetwork");
return currentNetwork;
};
mraid.setNetwork = function (newValue) {
log.i("mraid.setNetwork: " + newValue);
currentNetwork = newValue;
};
mraid.getHeading = function () {
log.i("mraid.getHeading");
return headingValue;
};
mraid.getKeyboardState = function () {
log.i("mraid.getKeyboardState");
return currentKeyboardState;
}
/**
* extended methods
**/
mraid.playAudio = function(url) {
log.i("mraid.playAudio " + url);
if (!mraid.supports(mraid.SUPPORTED_FEATURES.AUDIO)) {
mraidUtils.broadcastEvent(mraid.EVENTS.ERROR, "playAudio is not
supported", "playAudio");
return;
}
mraidBridge.notifyNative("playAudio", url);
};
mraid.openCamera = function () {
log.i("mraid.openCamera");
if (!mraid.supports(mraid.SUPPORTED_FEATURES.CAMERA)) {
mraidUtils.broadcastEvent(mraid.EVENTS.ERROR, "openCamera is not
supported", "openCamera");
return;
}
mraidBridge.notifyNative("openCamera");
}
/**
* event dispatchers
**/
mraid.fireShakeEvent = function() {
log.i("mraid.fireShakeEvent");
mraidUtils.broadcastEvent(mraid.EVENTS.SHAKE);
}
mraid.fireTiltChangeEvent = function(x, y, z) {
log.i("mraid.fireTiltChangeEvent, x: " + x + " y: " + y + " z: " + z);
tiltValues.x = x;
tiltValues.y = y;
tiltValues.z = z;
mraidUtils.broadcastEvent(mraid.EVENTS.TILTCHANGE, x, y, z);
}
mraid.fireHeadingChangeEvent = function(val) {
log.i("mraid.fireHeadingChangeEvent, val: " + val);
if (headingValue != val) {
headingValue = val;
mraidUtils.broadcastEvent(mraid.EVENTS.HEADINGCHANGE, val);
}
}
mraid.fireNetworkChangeEvent = function(network) {
log.d("mraid.fireNetworkChangeEvent: " + network);
if (currentNetwork != network) {
currentNetwork = network;
mraidUtils.broadcastEvent(mraid.EVENTS.NETWORKCHANGE, network);
}
}
mraid.fireKeyboardStateChangeEvent = function(state) {
log.d("mraid.fireKeyboardStateChangeEvent: " + state);
if (currentKeyboardState !== state) {
currentKeyboardState = state;
mraidUtils.broadcastEvent(mraid.EVENTS.KEYBOARDSTATECHANGE, state);
}
}
/**
* mraid functionalities
**/
(function() {
if (console.oldLog === undefined) {
console.oldLog = console.log;
console.log = function(log) {
if (console.oldLog !== undefined) {
console.oldLog(log);
}
var LOG_LEVEL = {
"DEBUG" : 0,
"INFO" : 1,
"WARNING" : 2,
"ERROR" : 3
};
log.d = function(msg) {
if (logLevel <= LOG_LEVEL.DEBUG) {
console.log("[DEBUG] " + msg);
}
};
log.i = function(msg) {
if (logLevel <= LOG_LEVEL.INFO) {
console.log("[INFO] " + msg);
}
};
log.w = function(msg) {
if (logLevel <= LOG_LEVEL.WARN) {
console.log("[WARN] " + msg);
}
};
log.e = function(msg) {
console.log("[ERROR] " + msg);
};
} ());
/**
* console logger
**/
(function() {
log.i("init mraid...");
/**
* globals
**/
var mraid = window.mraid = {};
/**
* constants
**/
var VERSION = "3.0";
/**
* states
**/
var supportedFeatures = {};
var orientationProperties = {
"allowOrientationChange" : true,
"forceOrientation" : DEVICE_ORIENTATIONS.NONE
};
var currentAppOrientation = {
"orientation" : DEVICE_ORIENTATIONS.NONE,
"locked" : false
};
var currentPosition = {
"x" : 0,
"y" : 0,
"width" : 0,
"height" : 0
};
var defaultPosition = {
"x" : 0,
"y" : 0,
"width" : 0,
"height" : 0
};
var expandProperties = {
"width" : 0,
"height" : 0,
"useCustomClose" : false,
"isModal" : true
};
var maxSize = {
"width" : 0,
"height" : 0
};
var screenSize = {
"width" : 0,
"height" : 0
};
var resizeProperties = {
"width" : 0,
"height" : 0,
"offsetX" : 0,
"offsetY" : 0,
"customClosePosition" : CUSTOM_CLOSE_POSITION.TOP_RIGHT,
"allowOffscreen" : true
};
var locationData = {
"lat" : 0.0,
"lon" : 0.0,
"type" : LOCATION_PROVIDER_TYPES.GPS,
"accuracy" : 0.0,
"lastfix" : 0,
"ipservice" : ""
};
var exposureProperties = {
"exposedPercentage" : 0,
"visibleRectangle" : {},
"occlusionRectangles" : null // not used in this version
};
bridge.setPlacementType = function(pt) {
placementType = pt;
};
currentPosition.x = x;
currentPosition.y = y;
currentPosition.width = width;
currentPosition.height = height;
var customClosePosition =
properties.hasOwnProperty("customClosePosition") ?
properties.customClosePosition : resizeProperties.customClosePosition;
log.d("customClosePosition " + customClosePosition);
resizeUtil.fitResizeViewOnScreen = function(properties) {
log.d("fitResizeViewOnScreen");
log.d("defaultPosition " + defaultPosition.x + " " + defaultPosition.y);
log.d("offset " + properties.offsetX + " " + properties.offsetY);
if (resizeUtil.isRectContained(maxRect, resizeRect)) {
log.d("no adjustment necessary");
return adjustments;
}
return adjustments;
};
this.add = function(func) {
var id = String(func);
if (!listeners[id]) {
listeners[id] = func;
this.count++;
}
};
this.remove = function(func) {
var id = String(func);
if (listeners[id]) {
listeners[id] = null;
delete listeners[id];
this.count--;
return true;
} else {
return false;
}
};
this.removeAll = function() {
for (var id in listeners) {
if (listeners.hasOwnProperty(id)) {
this.remove(listeners[id]);
}
}
};
this.broadcast = function(args) {
for (var id in listeners) {
if (listeners.hasOwnProperty(id)) {
listeners[id].apply(mraid, args);
}
}
};
this.toString = function() {
var out = [event, ':'];
for (var id in listeners) {
if (listeners.hasOwnProperty(id)) {
out.push('|', id, '|');
}
}
return out.join('');
};
};
/**
* validators
*
* The action parameter is a string which is the name of the setter function
which called this function
* (in other words, setExpandPropeties, setOrientationProperties, or
setResizeProperties).
* It serves both as the key to get the the appropriate set of validating
functions from the allValidators object
* as well as the action parameter of any error event that may be thrown.
*
* added location-data validation
**/
/**
* mraid properties
**/
mraid.supports = function(feature) {
log.i("mraid.supports: " + feature + " " + supportedFeatures[feature]);
var retval = supportedFeatures[feature];
if (typeof retval === "undefined") {
retval = false;
}
return retval;
};
mraid.getPlacementType = function() {
log.i("mraid.getPlacementType");
return placementType;
};
mraid.getOrientationProperties = function() {
log.i("mraid.getOrientationProperties");
var properties = {};
properties.allowOrientationChange =
orientationProperties.allowOrientationChange;
properties.forceOrientation = orientationProperties.forceOrientation;
return properties;
};
mraid.setOrientationProperties = function(properties) {
log.i("mraid.setOrientationProperties...");
if (!validate(properties, "setOrientationProperties")) {
log.e("validation failed!");
return;
}
orientationProperties.allowOrientationChange =
newOrientationProperties.allowOrientationChange;
orientationProperties.forceOrientation =
newOrientationProperties.forceOrientation;
notifyNative("setOrientationProperties",
JSON.stringify(orientationProperties));
};
mraid.getCurrentAppOrientation = function() {
log.i("mraid.getCurrentAppOrientation");
mraid.getCurrentPosition = function() {
log.i("mraid.getCurrentPosition");
var position = {
"x": currentPosition.x,
"y": currentPosition.y,
"width": currentPosition.width,
"height": currentPosition.height
};
return position;
};
mraid.getDefaultPosition = function() {
log.i("mraid.getDefaultPosition");
var position = {
"x": defaultPosition.x,
"y": defaultPosition.y,
"width": defaultPosition.width,
"height": defaultPosition.height
};
return position;
};
mraid.getState = function() {
log.i("mraid.getState: " + state);
return state;
};
mraid.getExpandProperties = function() {
log.i("mraid.getExpandProperties");
var properties = {
"width" : expandProperties.width,
"height" : expandProperties.height,
"useCustomClose" : expandProperties.useCustomClose,
"isModal" : expandProperties.isModal
};
return properties;
};
mraid.setExpandProperties = function(properties) {
log.i("mraid.setExpandProperties");
if (!validate(properties, "setExpandProperties")) {
log.e("validation failed!");
return;
}
// In MRAID v2.0, all expanded ads by definition cover the entire screen,
// so the only property that the native side has to know about is
useCustomClose.
// (That is, the width and height properties are not needed by the native
code.)
if (expandProperties.useCustomClose !== oldUseCustomClose) {
mraid.useCustomClose(properties.useCustomClose);
}
};
mraid.getMaxSize = function() {
log.i("mraid.getMaxSize: " + maxSize.width + " x " + maxSize.height);
mraid.getScreenSize = function() {
log.i("mraid.getScreenSize: " + screenSize.width + " x " +
screenSize.height);
mraid.getResizeProperties = function() {
log.i("mraid.getResizeProperties");
var properties = {
"width" : resizeProperties.width,
"height" : resizeProperties.height,
"offsetX" : resizeProperties.offsetX,
"offsetY" : resizeProperties.offsetY,
"customClosePosition" : resizeProperties.customClosePosition,
"allowOffscreen" : resizeProperties.allowOffscreen
};
return properties;
};
mraid.setResizeProperties = function(properties) {
log.i("mraid.setResizeProperties");
isResizeReady = false;
// The properties object passed into this function must contain width,
height, offsetX, offsetY.
// The remaining two properties are optional.
var rwProps = [ "width", "height", "offsetX", "offsetY" ];
for (var i = 0; i < rwProps.length; i++) {
var propname = rwProps[i];
if (!properties.hasOwnProperty(propname)) {
var message = "required property " + propname + " is missing";
log.e(message);
broadcastEvent(EVENTS.ERROR, message, "setResizeProperties");
return;
}
}
if (!validate(properties, "setResizeProperties")) {
log.e("validation failed!");
return;
}
if (!allowOffscreen) {
if (properties.width > maxSize.width || properties.height >
maxSize.height) {
var message = "Resize width or height is greater than the maxSize
width or height!";
log.e(message);
broadcastEvent(EVENTS.ERROR, message, "setResizeProperties");
return;
}
adjustments = resizeUtil.fitResizeViewOnScreen(properties);
} else if (!resizeUtil.isCloseRegionOnScreen(properties)) {
var message = "Close event region will not appear entirely onscreen!";
log.e(message);
broadcastEvent(EVENTS.ERROR, message, "setResizeProperties");
return;
}
var params = {
"width" : resizeProperties.width,
"height" : resizeProperties.height,
"offsetX" : resizeProperties.offsetX + adjustments.x,
"offsetY" : resizeProperties.offsetY + adjustments.y,
"customClosePosition" : resizeProperties.customClosePosition,
"allowOffscreen" : resizeProperties.allowOffscreen
};
notifyNative("setResizeProperties", JSON.stringify(params));
isResizeReady = true;
};
mraid.getLocation = function() {
if (!validate(locationData, "locationData")) {
log.e("invalid location data!");
return -1;
}
var data = {
"lat" : locationData.lat,
"lon" : locationData.lon,
"type" : locationData.type,
"accuracy" : locationData.accuracy,
"lastfix" : locationData.lastfix,
"ipservice" : locationData.ipservice
};
return data;
};
/**
* mraid methods
**/
mraid.getVersion = function() {
log.i("mraid.getVersion: " + VERSION);
return VERSION;
};
if (!event || !listener) {
broadcastEvent(EVENTS.ERROR, "Both event and listener are required.",
"addEventListener");
return;
}
if (!contains(event, EVENTS)) {
broadcastEvent(EVENTS.ERROR, "Unknown MRAID event: " + event,
"addEventListener");
return;
}
if (!eventListeners[event]) {
eventListeners[event] = new EventListeners(event);
}
eventListeners[event].add(listener);
};
if (!event) {
broadcastEvent(EVENTS.ERROR, "Event is required.",
"removeEventListener");
return;
}
if (!contains(event, EVENTS)) {
broadcastEvent(EVENTS.ERROR, "Unknown MRAID event: " + event,
"removeEventListener");
return;
}
if (eventListeners[event]) {
if (!listener) {
eventListeners[event].removeAll();
} else if (!eventListeners[event].remove(listener)) {
broadcastEvent(EVENTS.ERROR, "Listener not currently registered for
event.", "removeEventListener");
}
}
mraid.open = function(url) {
log.i("mraid.open: " + url);
if (!url) {
broadcastEvent(EVENTS.ERROR, "Invalid URL: " + url, "open");
return;
}
notifyNative("open", url);
};
mraid.close = function() {
log.i("mraid.close");
notifyNative("close");
};
mraid.unload = function() {
log.i("mraid.unload");
notifyNative("unload");
};
mraid.useCustomClose = function(shouldUseCustomClose) {
log.i("mraid.useCustomClose: " + shouldUseCustomClose);
expandProperties.useCustomClose = shouldUseCustomClose;
notifyNative("useCustomClose", shouldUseCustomClose);
};
mraid.expand = function(url) {
log.i("mraid.expand: " + (url === undefined) ? "(1-part)" : url);
mraid.isViewable = function() {
log.i("mraid.isViewable");
return isViewable;
};
mraid.playVideo = function(uri) {
log.i("mraid.playVideo: " + uri);
if (!uri) {
broadcastEvent(EVENTS.ERROR, "Invalid URI: " + uri, "playVideo");
return;
}
notifyNative("playVideo", uri);
};
mraid.resize = function() {
log.i("mraid.resize");
notifyNative("resize", JSON.stringify(resizeProperties));
};
mraid.storePicture = function(uri) {
log.i("mraid.storePicture: " + uri);
if (!mraid.supports(mraid.SUPPORTED_FEATURES.STOREPICTURE)) {
broadcastEvent(EVENTS.ERROR, "storePicture is not supported",
"storePicture");
return;
}
if (!uri) {
broadcastEvent(EVENTS.ERROR, "Invalid URI: " + uri, "storePicture");
return;
}
notifyNative("storePicture", uri);
};
mraid.createCalendarEvent = function(parameters) {
log.i("mraid.createCalendarEvent");
if (!mraid.supports(mraid.SUPPORTED_FEATURES.CALENDAR)) {
broadcastEvent(EVENTS.ERROR, "createCalendarEvent is not supported",
"createCalendarEvent");
return;
}
notifyNative("createCalendarEvent", JSON.stringify(parameters));
};
/**
* event dispatchers
**/
mraid.fireErrorEvent = function(message, action) {
broadcastEvent(EVENTS.ERROR, message, action);
};
mraid.fireReadyEvent = function() {
broadcastEvent(EVENTS.READY);
};
mraid.fireSizeChangeEvent = function(width, height) {
screenSize.width = width;
screenSize.height = height;
broadcastEvent(EVENTS.SIZECHANGE, width, height);
};
mraid.fireStateChangeEvent = function(newState) {
if (state !== newState) {
state = newState;
broadcastEvent(EVENTS.STATECHANGE, state);
}
};
mraid.fireViewableChangeEvent = function(newIsViewable) {
if (isViewable !== newIsViewable) {
isViewable = newIsViewable;
broadcastEvent(EVENTS.VIEWABLECHANGE, isViewable);
}
};
mraid.fireAudioVolumeChangeEvent = function(percentage) {
if (volumePercentage !== percentage) {
volumePercentage = volumePercentage;
broadcastEvent(EVENTS.AUDIOVOLUMECHANGE, percentage);
}
};
// TODO: VPAID
/**
* pokkt extended featuers
**/
(function() {
log.i("setting up: mraid-extensions...");
mraid.SUPPORTED_FEATURES.AUDIO = "audio";
mraid.SUPPORTED_FEATURES.CAMERA = "camera";
mraid.SUPPORTED_FEATURES.NETWORK = "network";
mraid.SUPPORTED_FEATURES.SHAKE = "shake";
mraid.SUPPORTED_FEATURES.TILT = "tilt";
mraid.SUPPORTED_FEATURES.HEADING = "heading";
mraid.SUPPORTED_FEATURES.ORIENTATION = "orientation";
mraid.SUPPORTED_FEATURES.MAP = "map";
mraid.EVENTS.SHAKE = "shake";
mraid.EVENTS.TILTCHANGE = "tiltChange";
mraid.EVENTS.HEADINGCHANGE = "headingChange";
mraid.EVENTS.LOCATIONCHANGE = "locationChange";
mraid.EVENTS.NETWORKCHANGE = "networkChange";
mraid.EVENTS.KEYBOARDSTATECHANGE = "keyboardStateChange";
/**
* pokkt specific states
**/
var shakeProperties = {
"interval" : 0,
"intensity" : 0
};
var tiltProperties = {
"interval" : 0,
"intensity" : 0
};
var headingProperties = {
"interval" : 0,
"intensity" : 0
};
var tiltValues = {
"x" : 0,
"y" : 0,
"z" : 0
};
var headingValue = 0;
var currentNetwork = "";
var currentKeyboardState = 0;
/**
* pokkt specific validators
**/
mraidUtils.allValidators.setShakeProperties =
mraidUtils.allValidators.setTiltProperties =
mraidUtils.allValidators.setHeadingProperties = {
"intensity":function(value) { return !isNaN(value); },
"interval":function(value) { return !isNaN(value); }
};
mraidUtils.allValidators.setTilt = {
"x":function(value) { return !isNaN(value); },
"y":function(value) { return !isNaN(value); },
"z":function(value) { return !isNaN(value); }
};
/**
* pokkt's extended properties
**/
mraid.setShakeProperties = function(properties) {
log.i("mraid.setShakeProperties: " + properties);
if (!mraidUtils.validate(properties, "setShakeProperties")) {
log.e("validation failed!");
return;
}
shakeProperties = properties;
mraidBridge.notifyNative("setShakeProperties", JSON.stringify(properties));
};
mraid.getShakeProperties = function() {
log.i("mraid.getShakeProperties");
mraid.setTiltProperties = function(properties) {
log.i("mraid.setTiltProperties: " + properties);
if (!mraidUtils.validate(properties, "setTiltProperties")) {
log.e("validation failed!");
return;
}
tiltProperties = properties;
mraidBridge.notifyNative("setTiltProperties", JSON.stringify(properties));
};
mraid.getTiltProperties = function() {
log.i("mraid.getTiltProperties");
mraid.setHeadingProperties = function(properties) {
log.i("mraid.setHeadingProperties: " + properties);
if (!mraidUtils.validate(properties, "setHeadingProperties")) {
log.e("validation failed!");
return;
}
headingProperties = properties;
mraidBridge.notifyNative("setHeadingProperties",
JSON.stringify(properties));
};
mraid.getHeadingProperties = function() {
log.i("mraid.getHeadingProperties");
mraid.getTilt = function () {
log.i("mraid.getTilt");
tiltValues = newValue;
};
mraid.getNetwork = function () {
log.i("mraid.getNetwork");
return currentNetwork;
};
mraid.getHeading = function () {
log.i("mraid.getHeading");
return headingValue;
};
/**
* extended methods
**/
mraid.playAudio = function(url) {
log.i("mraid.playAudio " + url);
if (!mraid.supports(mraid.SUPPORTED_FEATURES.AUDIO)) {
mraidUtils.broadcastEvent(mraid.EVENTS.ERROR, "playAudio is not
supported", "playAudio");
return;
}
mraidBridge.notifyNative("playAudio", url);
};
mraid.openCamera = function () {
log.i("mraid.openCamera");
if (!mraid.supports(mraid.SUPPORTED_FEATURES.CAMERA)) {
mraidUtils.broadcastEvent(mraid.EVENTS.ERROR, "openCamera is not
supported", "openCamera");
return;
}
mraidBridge.notifyNative("openCamera");
}
/**
* event dispatchers
**/
mraid.fireShakeEvent = function() {
log.i("mraid.fireShakeEvent");
mraidUtils.broadcastEvent(mraid.EVENTS.SHAKE);
}
mraid.fireTiltChangeEvent = function(x, y, z) {
log.i("mraid.fireTiltChangeEvent, x: " + x + " y: " + y + " z: " + z);
tiltValues.x = x;
tiltValues.y = y;
tiltValues.z = z;
mraidUtils.broadcastEvent(mraid.EVENTS.TILTCHANGE, x, y, z);
}
mraid.fireHeadingChangeEvent = function(val) {
log.i("mraid.fireHeadingChangeEvent, val: " + val);
if (headingValue != val) {
headingValue = val;
mraidUtils.broadcastEvent(mraid.EVENTS.HEADINGCHANGE, val);
}
}
mraid.fireNetworkChangeEvent = function(network) {
log.d("mraid.fireNetworkChangeEvent: " + network);
if (currentNetwork != network) {
currentNetwork = network;
mraidUtils.broadcastEvent(mraid.EVENTS.NETWORKCHANGE, network);
}
}
mraid.fireKeyboardStateChangeEvent = function(state) {
log.d("mraid.fireKeyboardStateChangeEvent: " + state);
if (currentKeyboardState !== state) {
currentKeyboardState = state;
mraidUtils.broadcastEvent(mraid.EVENTS.KEYBOARDSTATECHANGE, state);
}
}
/**
* mraid functionalities
**/
(function() {
if (console.oldLog === undefined) {
console.oldLog = console.log;
console.log = function(log) {
if (console.oldLog !== undefined) {
console.oldLog(log);
}
var LOG_LEVEL = {
"DEBUG" : 0,
"INFO" : 1,
"WARNING" : 2,
"ERROR" : 3
};
log.d = function(msg) {
if (logLevel <= LOG_LEVEL.DEBUG) {
console.log("[DEBUG] " + msg);
}
};
log.i = function(msg) {
if (logLevel <= LOG_LEVEL.INFO) {
console.log("[INFO] " + msg);
}
};
log.w = function(msg) {
if (logLevel <= LOG_LEVEL.WARN) {
console.log("[WARN] " + msg);
}
};
log.e = function(msg) {
console.log("[ERROR] " + msg);
};
} ());
/**
* console logger
**/
(function() {
log.i("init mraid...");
/**
* globals
**/
var mraid = window.mraid = {};
/**
* constants
**/
var VERSION = "3.0";
/**
* states
**/
var supportedFeatures = {};
var orientationProperties = {
"allowOrientationChange" : true,
"forceOrientation" : DEVICE_ORIENTATIONS.NONE
};
var currentAppOrientation = {
"orientation" : DEVICE_ORIENTATIONS.NONE,
"locked" : false
};
var currentPosition = {
"x" : 0,
"y" : 0,
"width" : 0,
"height" : 0
};
var defaultPosition = {
"x" : 0,
"y" : 0,
"width" : 0,
"height" : 0
};
var expandProperties = {
"width" : 0,
"height" : 0,
"useCustomClose" : false,
"isModal" : true
};
var maxSize = {
"width" : 0,
"height" : 0
};
var screenSize = {
"width" : 0,
"height" : 0
};
var resizeProperties = {
"width" : 0,
"height" : 0,
"offsetX" : 0,
"offsetY" : 0,
"customClosePosition" : CUSTOM_CLOSE_POSITION.TOP_RIGHT,
"allowOffscreen" : true
};
var locationData = {
"lat" : 0.0,
"lon" : 0.0,
"type" : LOCATION_PROVIDER_TYPES.GPS,
"accuracy" : 0.0,
"lastfix" : 0,
"ipservice" : ""
};
var exposureProperties = {
"exposedPercentage" : 0,
"visibleRectangle" : {},
"occlusionRectangles" : null // not used in this version
};
bridge.setPlacementType = function(pt) {
placementType = pt;
};
currentPosition.x = x;
currentPosition.y = y;
currentPosition.width = width;
currentPosition.height = height;
var customClosePosition =
properties.hasOwnProperty("customClosePosition") ?
properties.customClosePosition : resizeProperties.customClosePosition;
log.d("customClosePosition " + customClosePosition);
resizeUtil.fitResizeViewOnScreen = function(properties) {
log.d("fitResizeViewOnScreen");
log.d("defaultPosition " + defaultPosition.x + " " + defaultPosition.y);
log.d("offset " + properties.offsetX + " " + properties.offsetY);
if (resizeUtil.isRectContained(maxRect, resizeRect)) {
log.d("no adjustment necessary");
return adjustments;
}
return adjustments;
};
this.add = function(func) {
var id = String(func);
if (!listeners[id]) {
listeners[id] = func;
this.count++;
}
};
this.remove = function(func) {
var id = String(func);
if (listeners[id]) {
listeners[id] = null;
delete listeners[id];
this.count--;
return true;
} else {
return false;
}
};
this.removeAll = function() {
for (var id in listeners) {
if (listeners.hasOwnProperty(id)) {
this.remove(listeners[id]);
}
}
};
this.broadcast = function(args) {
for (var id in listeners) {
if (listeners.hasOwnProperty(id)) {
listeners[id].apply(mraid, args);
}
}
};
this.toString = function() {
var out = [event, ':'];
for (var id in listeners) {
if (listeners.hasOwnProperty(id)) {
out.push('|', id, '|');
}
}
return out.join('');
};
};
/**
* validators
*
* The action parameter is a string which is the name of the setter function
which called this function
* (in other words, setExpandPropeties, setOrientationProperties, or
setResizeProperties).
* It serves both as the key to get the the appropriate set of validating
functions from the allValidators object
* as well as the action parameter of any error event that may be thrown.
*
* added location-data validation
**/
/**
* mraid properties
**/
mraid.supports = function(feature) {
log.i("mraid.supports: " + feature + " " + supportedFeatures[feature]);
var retval = supportedFeatures[feature];
if (typeof retval === "undefined") {
retval = false;
}
return retval;
};
mraid.getPlacementType = function() {
log.i("mraid.getPlacementType");
return placementType;
};
mraid.getOrientationProperties = function() {
log.i("mraid.getOrientationProperties");
mraid.setOrientationProperties = function(properties) {
log.i("mraid.setOrientationProperties...");
if (!validate(properties, "setOrientationProperties")) {
log.e("validation failed!");
return;
}
orientationProperties.allowOrientationChange =
newOrientationProperties.allowOrientationChange;
orientationProperties.forceOrientation =
newOrientationProperties.forceOrientation;
notifyNative("setOrientationProperties",
JSON.stringify(orientationProperties));
};
mraid.getCurrentAppOrientation = function() {
log.i("mraid.getCurrentAppOrientation");
mraid.getCurrentPosition = function() {
log.i("mraid.getCurrentPosition");
var position = {
"x": currentPosition.x,
"y": currentPosition.y,
"width": currentPosition.width,
"height": currentPosition.height
};
return position;
};
mraid.getDefaultPosition = function() {
log.i("mraid.getDefaultPosition");
var position = {
"x": defaultPosition.x,
"y": defaultPosition.y,
"width": defaultPosition.width,
"height": defaultPosition.height
};
return position;
};
mraid.getState = function() {
log.i("mraid.getState: " + state);
return state;
};
mraid.getExpandProperties = function() {
log.i("mraid.getExpandProperties");
var properties = {
"width" : expandProperties.width,
"height" : expandProperties.height,
"useCustomClose" : expandProperties.useCustomClose,
"isModal" : expandProperties.isModal
};
return properties;
};
mraid.setExpandProperties = function(properties) {
log.i("mraid.setExpandProperties");
if (!validate(properties, "setExpandProperties")) {
log.e("validation failed!");
return;
}
// In MRAID v2.0, all expanded ads by definition cover the entire screen,
// so the only property that the native side has to know about is
useCustomClose.
// (That is, the width and height properties are not needed by the native
code.)
if (expandProperties.useCustomClose !== oldUseCustomClose) {
mraid.useCustomClose(properties.useCustomClose);
}
};
mraid.getMaxSize = function() {
log.i("mraid.getMaxSize: " + maxSize.width + " x " + maxSize.height);
mraid.getScreenSize = function() {
log.i("mraid.getScreenSize: " + screenSize.width + " x " +
screenSize.height);
mraid.getResizeProperties = function() {
log.i("mraid.getResizeProperties");
var properties = {
"width" : resizeProperties.width,
"height" : resizeProperties.height,
"offsetX" : resizeProperties.offsetX,
"offsetY" : resizeProperties.offsetY,
"customClosePosition" : resizeProperties.customClosePosition,
"allowOffscreen" : resizeProperties.allowOffscreen
};
return properties;
};
mraid.setResizeProperties = function(properties) {
log.i("mraid.setResizeProperties");
isResizeReady = false;
// The properties object passed into this function must contain width,
height, offsetX, offsetY.
// The remaining two properties are optional.
var rwProps = [ "width", "height", "offsetX", "offsetY" ];
for (var i = 0; i < rwProps.length; i++) {
var propname = rwProps[i];
if (!properties.hasOwnProperty(propname)) {
var message = "required property " + propname + " is missing";
log.e(message);
broadcastEvent(EVENTS.ERROR, message, "setResizeProperties");
return;
}
}
if (!validate(properties, "setResizeProperties")) {
log.e("validation failed!");
return;
}
if (!allowOffscreen) {
if (properties.width > maxSize.width || properties.height >
maxSize.height) {
var message = "Resize width or height is greater than the maxSize
width or height!";
log.e(message);
broadcastEvent(EVENTS.ERROR, message, "setResizeProperties");
return;
}
adjustments = resizeUtil.fitResizeViewOnScreen(properties);
} else if (!resizeUtil.isCloseRegionOnScreen(properties)) {
var message = "Close event region will not appear entirely onscreen!";
log.e(message);
broadcastEvent(EVENTS.ERROR, message, "setResizeProperties");
return;
}
var params = {
"width" : resizeProperties.width,
"height" : resizeProperties.height,
"offsetX" : resizeProperties.offsetX + adjustments.x,
"offsetY" : resizeProperties.offsetY + adjustments.y,
"customClosePosition" : resizeProperties.customClosePosition,
"allowOffscreen" : resizeProperties.allowOffscreen
};
notifyNative("setResizeProperties", JSON.stringify(params));
isResizeReady = true;
};
mraid.getLocation = function() {
if (!validate(locationData, "locationData")) {
log.e("invalid location data!");
return -1;
}
var data = {
"lat" : locationData.lat,
"lon" : locationData.lon,
"type" : locationData.type,
"accuracy" : locationData.accuracy,
"lastfix" : locationData.lastfix,
"ipservice" : locationData.ipservice
};
return data;
};
/**
* mraid methods
**/
mraid.getVersion = function() {
log.i("mraid.getVersion: " + VERSION);
return VERSION;
};
if (!event || !listener) {
broadcastEvent(EVENTS.ERROR, "Both event and listener are required.",
"addEventListener");
return;
}
if (!contains(event, EVENTS)) {
broadcastEvent(EVENTS.ERROR, "Unknown MRAID event: " + event,
"addEventListener");
return;
}
if (!eventListeners[event]) {
eventListeners[event] = new EventListeners(event);
}
eventListeners[event].add(listener);
};
if (!event) {
broadcastEvent(EVENTS.ERROR, "Event is required.",
"removeEventListener");
return;
}
if (!contains(event, EVENTS)) {
broadcastEvent(EVENTS.ERROR, "Unknown MRAID event: " + event,
"removeEventListener");
return;
}
if (eventListeners[event]) {
if (!listener) {
eventListeners[event].removeAll();
} else if (!eventListeners[event].remove(listener)) {
broadcastEvent(EVENTS.ERROR, "Listener not currently registered for
event.", "removeEventListener");
}
}
mraid.open = function(url) {
log.i("mraid.open: " + url);
if (!url) {
broadcastEvent(EVENTS.ERROR, "Invalid URL: " + url, "open");
return;
}
notifyNative("open", url);
};
mraid.close = function() {
log.i("mraid.close");
notifyNative("close");
};
mraid.unload = function() {
log.i("mraid.unload");
notifyNative("unload");
};
mraid.useCustomClose = function(shouldUseCustomClose) {
log.i("mraid.useCustomClose: " + shouldUseCustomClose);
expandProperties.useCustomClose = shouldUseCustomClose;
notifyNative("useCustomClose", shouldUseCustomClose);
};
mraid.expand = function(url) {
log.i("mraid.expand: " + (url === undefined) ? "(1-part)" : url);
mraid.isViewable = function() {
log.i("mraid.isViewable");
return isViewable;
};
mraid.playVideo = function(uri) {
log.i("mraid.playVideo: " + uri);
if (!uri) {
broadcastEvent(EVENTS.ERROR, "Invalid URI: " + uri, "playVideo");
return;
}
notifyNative("playVideo", uri);
};
mraid.resize = function() {
log.i("mraid.resize");
notifyNative("resize", JSON.stringify(resizeProperties));
};
mraid.storePicture = function(uri) {
log.i("mraid.storePicture: " + uri);
if (!mraid.supports(mraid.SUPPORTED_FEATURES.STOREPICTURE)) {
broadcastEvent(EVENTS.ERROR, "storePicture is not supported",
"storePicture");
return;
}
if (!uri) {
broadcastEvent(EVENTS.ERROR, "Invalid URI: " + uri, "storePicture");
return;
}
notifyNative("storePicture", uri);
};
mraid.createCalendarEvent = function(parameters) {
log.i("mraid.createCalendarEvent");
if (!mraid.supports(mraid.SUPPORTED_FEATURES.CALENDAR)) {
broadcastEvent(EVENTS.ERROR, "createCalendarEvent is not supported",
"createCalendarEvent");
return;
}
notifyNative("createCalendarEvent", JSON.stringify(parameters));
};
/**
* event dispatchers
**/
mraid.fireErrorEvent = function(message, action) {
broadcastEvent(EVENTS.ERROR, message, action);
};
mraid.fireReadyEvent = function() {
broadcastEvent(EVENTS.READY);
};
mraid.fireStateChangeEvent = function(newState) {
if (state !== newState) {
state = newState;
broadcastEvent(EVENTS.STATECHANGE, state);
}
};
mraid.fireViewableChangeEvent = function(newIsViewable) {
if (isViewable !== newIsViewable) {
isViewable = newIsViewable;
broadcastEvent(EVENTS.VIEWABLECHANGE, isViewable);
}
};
mraid.fireAudioVolumeChangeEvent = function(percentage) {
if (volumePercentage !== percentage) {
volumePercentage = volumePercentage;
broadcastEvent(EVENTS.AUDIOVOLUMECHANGE, percentage);
}
};
// TODO: VPAID
/**
* pokkt extended featuers
**/
(function() {
log.i("setting up: mraid-extensions...");
/**
* pokkt specific constants
**/
var NETWORK = mraid.NETWORK = {
OFFLINE :'offline',
WIFI :'wifi',
CELL :'cell',
UNKNOWN :'unknown'
};
mraid.SUPPORTED_FEATURES.AUDIO = "audio";
mraid.SUPPORTED_FEATURES.CAMERA = "camera";
mraid.SUPPORTED_FEATURES.NETWORK = "network";
mraid.SUPPORTED_FEATURES.SHAKE = "shake";
mraid.SUPPORTED_FEATURES.TILT = "tilt";
mraid.SUPPORTED_FEATURES.HEADING = "heading";
mraid.SUPPORTED_FEATURES.ORIENTATION = "orientation";
mraid.SUPPORTED_FEATURES.MAP = "map";
mraid.EVENTS.SHAKE = "shake";
mraid.EVENTS.TILTCHANGE = "tiltChange";
mraid.EVENTS.HEADINGCHANGE = "headingChange";
mraid.EVENTS.LOCATIONCHANGE = "locationChange";
mraid.EVENTS.NETWORKCHANGE = "networkChange";
mraid.EVENTS.KEYBOARDSTATECHANGE = "keyboardStateChange";
/**
* pokkt specific states
**/
var shakeProperties = {
"interval" : 0,
"intensity" : 0
};
var tiltProperties = {
"interval" : 0,
"intensity" : 0
};
var headingProperties = {
"interval" : 0,
"intensity" : 0
};
var tiltValues = {
"x" : 0,
"y" : 0,
"z" : 0
};
var headingValue = 0;
var currentNetwork = "";
var currentKeyboardState = 0;
/**
* pokkt specific validators
**/
mraidUtils.allValidators.setShakeProperties =
mraidUtils.allValidators.setTiltProperties =
mraidUtils.allValidators.setHeadingProperties = {
"intensity":function(value) { return !isNaN(value); },
"interval":function(value) { return !isNaN(value); }
};
mraidUtils.allValidators.setTilt = {
"x":function(value) { return !isNaN(value); },
"y":function(value) { return !isNaN(value); },
"z":function(value) { return !isNaN(value); }
};
/**
* pokkt's extended properties
**/
mraid.setShakeProperties = function(properties) {
log.i("mraid.setShakeProperties: " + properties);
if (!mraidUtils.validate(properties, "setShakeProperties")) {
log.e("validation failed!");
return;
}
shakeProperties = properties;
mraidBridge.notifyNative("setShakeProperties", JSON.stringify(properties));
};
mraid.getShakeProperties = function() {
log.i("mraid.getShakeProperties");
mraid.setTiltProperties = function(properties) {
log.i("mraid.setTiltProperties: " + properties);
if (!mraidUtils.validate(properties, "setTiltProperties")) {
log.e("validation failed!");
return;
}
tiltProperties = properties;
mraidBridge.notifyNative("setTiltProperties", JSON.stringify(properties));
};
mraid.getTiltProperties = function() {
log.i("mraid.getTiltProperties");
mraid.setHeadingProperties = function(properties) {
log.i("mraid.setHeadingProperties: " + properties);
if (!mraidUtils.validate(properties, "setHeadingProperties")) {
log.e("validation failed!");
return;
}
headingProperties = properties;
mraidBridge.notifyNative("setHeadingProperties",
JSON.stringify(properties));
};
mraid.getHeadingProperties = function() {
log.i("mraid.getHeadingProperties");
mraid.getTilt = function () {
log.i("mraid.getTilt");
tiltValues = newValue;
};
mraid.getNetwork = function () {
log.i("mraid.getNetwork");
return currentNetwork;
};
mraid.getHeading = function () {
log.i("mraid.getHeading");
return headingValue;
};
mraid.getKeyboardState = function () {
log.i("mraid.getKeyboardState");
return currentKeyboardState;
}
/**
* extended methods
**/
mraid.playAudio = function(url) {
log.i("mraid.playAudio " + url);
if (!mraid.supports(mraid.SUPPORTED_FEATURES.AUDIO)) {
mraidUtils.broadcastEvent(mraid.EVENTS.ERROR, "playAudio is not
supported", "playAudio");
return;
}
mraidBridge.notifyNative("playAudio", url);
};
mraid.openCamera = function () {
log.i("mraid.openCamera");
if (!mraid.supports(mraid.SUPPORTED_FEATURES.CAMERA)) {
mraidUtils.broadcastEvent(mraid.EVENTS.ERROR, "openCamera is not
supported", "openCamera");
return;
}
mraidBridge.notifyNative("openCamera");
}
/**
* event dispatchers
**/
mraid.fireShakeEvent = function() {
log.i("mraid.fireShakeEvent");
mraidUtils.broadcastEvent(mraid.EVENTS.SHAKE);
}
mraid.fireTiltChangeEvent = function(x, y, z) {
log.i("mraid.fireTiltChangeEvent, x: " + x + " y: " + y + " z: " + z);
tiltValues.x = x;
tiltValues.y = y;
tiltValues.z = z;
mraidUtils.broadcastEvent(mraid.EVENTS.TILTCHANGE, x, y, z);
}
mraid.fireHeadingChangeEvent = function(val) {
log.i("mraid.fireHeadingChangeEvent, val: " + val);
if (headingValue != val) {
headingValue = val;
mraidUtils.broadcastEvent(mraid.EVENTS.HEADINGCHANGE, val);
}
}
mraid.fireNetworkChangeEvent = function(network) {
log.d("mraid.fireNetworkChangeEvent: " + network);
if (currentNetwork != network) {
currentNetwork = network;
mraidUtils.broadcastEvent(mraid.EVENTS.NETWORKCHANGE, network);
}
}
mraid.fireKeyboardStateChangeEvent = function(state) {
log.d("mraid.fireKeyboardStateChangeEvent: " + state);
if (currentKeyboardState !== state) {
currentKeyboardState = state;
mraidUtils.broadcastEvent(mraid.EVENTS.KEYBOARDSTATECHANGE, state);
}
}
/**
* mraid functionalities
**/
(function() {
if (console.oldLog === undefined) {
console.oldLog = console.log;
console.log = function(log) {
if (console.oldLog !== undefined) {
console.oldLog(log);
}
var LOG_LEVEL = {
"DEBUG" : 0,
"INFO" : 1,
"WARNING" : 2,
"ERROR" : 3
};
log.d = function(msg) {
if (logLevel <= LOG_LEVEL.DEBUG) {
console.log("[DEBUG] " + msg);
}
};
log.i = function(msg) {
if (logLevel <= LOG_LEVEL.INFO) {
console.log("[INFO] " + msg);
}
};
log.w = function(msg) {
if (logLevel <= LOG_LEVEL.WARN) {
console.log("[WARN] " + msg);
}
};
log.e = function(msg) {
console.log("[ERROR] " + msg);
};
} ());
/**
* console logger
**/
(function() {
log.i("init mraid...");
/**
* globals
**/
var mraid = window.mraid = {};
/**
* constants
**/
var VERSION = "3.0";
/**
* states
**/
var supportedFeatures = {};
var orientationProperties = {
"allowOrientationChange" : true,
"forceOrientation" : DEVICE_ORIENTATIONS.NONE
};
var currentAppOrientation = {
"orientation" : DEVICE_ORIENTATIONS.NONE,
"locked" : false
};
var currentPosition = {
"x" : 0,
"y" : 0,
"width" : 0,
"height" : 0
};
var defaultPosition = {
"x" : 0,
"y" : 0,
"width" : 0,
"height" : 0
};
var expandProperties = {
"width" : 0,
"height" : 0,
"useCustomClose" : false,
"isModal" : true
};
var maxSize = {
"width" : 0,
"height" : 0
};
var screenSize = {
"width" : 0,
"height" : 0
};
var resizeProperties = {
"width" : 0,
"height" : 0,
"offsetX" : 0,
"offsetY" : 0,
"customClosePosition" : CUSTOM_CLOSE_POSITION.TOP_RIGHT,
"allowOffscreen" : true
};
var locationData = {
"lat" : 0.0,
"lon" : 0.0,
"type" : LOCATION_PROVIDER_TYPES.GPS,
"accuracy" : 0.0,
"lastfix" : 0,
"ipservice" : ""
};
var exposureProperties = {
"exposedPercentage" : 0,
"visibleRectangle" : {},
"occlusionRectangles" : null // not used in this version
};
currentPosition.x = x;
currentPosition.y = y;
currentPosition.width = width;
currentPosition.height = height;
var customClosePosition =
properties.hasOwnProperty("customClosePosition") ?
properties.customClosePosition : resizeProperties.customClosePosition;
log.d("customClosePosition " + customClosePosition);
resizeUtil.fitResizeViewOnScreen = function(properties) {
log.d("fitResizeViewOnScreen");
log.d("defaultPosition " + defaultPosition.x + " " + defaultPosition.y);
log.d("offset " + properties.offsetX + " " + properties.offsetY);
if (resizeUtil.isRectContained(maxRect, resizeRect)) {
log.d("no adjustment necessary");
return adjustments;
}
return adjustments;
};
this.add = function(func) {
var id = String(func);
if (!listeners[id]) {
listeners[id] = func;
this.count++;
}
};
this.remove = function(func) {
var id = String(func);
if (listeners[id]) {
listeners[id] = null;
delete listeners[id];
this.count--;
return true;
} else {
return false;
}
};
this.removeAll = function() {
for (var id in listeners) {
if (listeners.hasOwnProperty(id)) {
this.remove(listeners[id]);
}
}
};
this.broadcast = function(args) {
for (var id in listeners) {
if (listeners.hasOwnProperty(id)) {
listeners[id].apply(mraid, args);
}
}
};
this.toString = function() {
var out = [event, ':'];
for (var id in listeners) {
if (listeners.hasOwnProperty(id)) {
out.push('|', id, '|');
}
}
return out.join('');
};
};
/**
* validators
*
* The action parameter is a string which is the name of the setter function
which called this function
* (in other words, setExpandPropeties, setOrientationProperties, or
setResizeProperties).
* It serves both as the key to get the the appropriate set of validating
functions from the allValidators object
* as well as the action parameter of any error event that may be thrown.
*
* added location-data validation
**/
/**
* mraid properties
**/
mraid.supports = function(feature) {
log.i("mraid.supports: " + feature + " " + supportedFeatures[feature]);
var retval = supportedFeatures[feature];
if (typeof retval === "undefined") {
retval = false;
}
return retval;
};
mraid.getPlacementType = function() {
log.i("mraid.getPlacementType");
return placementType;
};
mraid.getOrientationProperties = function() {
log.i("mraid.getOrientationProperties");
mraid.setOrientationProperties = function(properties) {
log.i("mraid.setOrientationProperties...");
if (!validate(properties, "setOrientationProperties")) {
log.e("validation failed!");
return;
}
orientationProperties.allowOrientationChange =
newOrientationProperties.allowOrientationChange;
orientationProperties.forceOrientation =
newOrientationProperties.forceOrientation;
notifyNative("setOrientationProperties",
JSON.stringify(orientationProperties));
};
mraid.getCurrentAppOrientation = function() {
log.i("mraid.getCurrentAppOrientation");
mraid.getCurrentPosition = function() {
log.i("mraid.getCurrentPosition");
var position = {
"x": currentPosition.x,
"y": currentPosition.y,
"width": currentPosition.width,
"height": currentPosition.height
};
return position;
};
mraid.getDefaultPosition = function() {
log.i("mraid.getDefaultPosition");
var position = {
"x": defaultPosition.x,
"y": defaultPosition.y,
"width": defaultPosition.width,
"height": defaultPosition.height
};
return position;
};
mraid.getState = function() {
log.i("mraid.getState: " + state);
return state;
};
mraid.getExpandProperties = function() {
log.i("mraid.getExpandProperties");
var properties = {
"width" : expandProperties.width,
"height" : expandProperties.height,
"useCustomClose" : expandProperties.useCustomClose,
"isModal" : expandProperties.isModal
};
return properties;
};
mraid.setExpandProperties = function(properties) {
log.i("mraid.setExpandProperties");
if (!validate(properties, "setExpandProperties")) {
log.e("validation failed!");
return;
}
// In MRAID v2.0, all expanded ads by definition cover the entire screen,
// so the only property that the native side has to know about is
useCustomClose.
// (That is, the width and height properties are not needed by the native
code.)
if (expandProperties.useCustomClose !== oldUseCustomClose) {
mraid.useCustomClose(properties.useCustomClose);
}
};
mraid.getMaxSize = function() {
log.i("mraid.getMaxSize: " + maxSize.width + " x " + maxSize.height);
mraid.getScreenSize = function() {
log.i("mraid.getScreenSize: " + screenSize.width + " x " +
screenSize.height);
mraid.getResizeProperties = function() {
log.i("mraid.getResizeProperties");
var properties = {
"width" : resizeProperties.width,
"height" : resizeProperties.height,
"offsetX" : resizeProperties.offsetX,
"offsetY" : resizeProperties.offsetY,
"customClosePosition" : resizeProperties.customClosePosition,
"allowOffscreen" : resizeProperties.allowOffscreen
};
return properties;
};
mraid.setResizeProperties = function(properties) {
log.i("mraid.setResizeProperties");
isResizeReady = false;
// The properties object passed into this function must contain width,
height, offsetX, offsetY.
// The remaining two properties are optional.
var rwProps = [ "width", "height", "offsetX", "offsetY" ];
for (var i = 0; i < rwProps.length; i++) {
var propname = rwProps[i];
if (!properties.hasOwnProperty(propname)) {
var message = "required property " + propname + " is missing";
log.e(message);
broadcastEvent(EVENTS.ERROR, message, "setResizeProperties");
return;
}
}
if (!validate(properties, "setResizeProperties")) {
log.e("validation failed!");
return;
}
if (!allowOffscreen) {
if (properties.width > maxSize.width || properties.height >
maxSize.height) {
var message = "Resize width or height is greater than the maxSize
width or height!";
log.e(message);
broadcastEvent(EVENTS.ERROR, message, "setResizeProperties");
return;
}
adjustments = resizeUtil.fitResizeViewOnScreen(properties);
} else if (!resizeUtil.isCloseRegionOnScreen(properties)) {
var message = "Close event region will not appear entirely onscreen!";
log.e(message);
broadcastEvent(EVENTS.ERROR, message, "setResizeProperties");
return;
}
var params = {
"width" : resizeProperties.width,
"height" : resizeProperties.height,
"offsetX" : resizeProperties.offsetX + adjustments.x,
"offsetY" : resizeProperties.offsetY + adjustments.y,
"customClosePosition" : resizeProperties.customClosePosition,
"allowOffscreen" : resizeProperties.allowOffscreen
};
notifyNative("setResizeProperties", JSON.stringify(params));
isResizeReady = true;
};
mraid.getLocation = function() {
if (!validate(locationData, "locationData")) {
log.e("invalid location data!");
return -1;
}
var data = {
"lat" : locationData.lat,
"lon" : locationData.lon,
"type" : locationData.type,
"accuracy" : locationData.accuracy,
"lastfix" : locationData.lastfix,
"ipservice" : locationData.ipservice
};
return data;
};
/**
* mraid methods
**/
mraid.getVersion = function() {
log.i("mraid.getVersion: " + VERSION);
return VERSION;
};
if (!event || !listener) {
broadcastEvent(EVENTS.ERROR, "Both event and listener are required.",
"addEventListener");
return;
}
if (!contains(event, EVENTS)) {
broadcastEvent(EVENTS.ERROR, "Unknown MRAID event: " + event,
"addEventListener");
return;
}
if (!eventListeners[event]) {
eventListeners[event] = new EventListeners(event);
}
eventListeners[event].add(listener);
};
if (!event) {
broadcastEvent(EVENTS.ERROR, "Event is required.",
"removeEventListener");
return;
}
if (!contains(event, EVENTS)) {
broadcastEvent(EVENTS.ERROR, "Unknown MRAID event: " + event,
"removeEventListener");
return;
}
if (eventListeners[event]) {
if (!listener) {
eventListeners[event].removeAll();
} else if (!eventListeners[event].remove(listener)) {
broadcastEvent(EVENTS.ERROR, "Listener not currently registered for
event.", "removeEventListener");
}
}
mraid.open = function(url) {
log.i("mraid.open: " + url);
if (!url) {
broadcastEvent(EVENTS.ERROR, "Invalid URL: " + url, "open");
return;
}
notifyNative("open", url);
};
mraid.close = function() {
log.i("mraid.close");
notifyNative("close");
};
mraid.unload = function() {
log.i("mraid.unload");
notifyNative("unload");
};
mraid.useCustomClose = function(shouldUseCustomClose) {
log.i("mraid.useCustomClose: " + shouldUseCustomClose);
expandProperties.useCustomClose = shouldUseCustomClose;
notifyNative("useCustomClose", shouldUseCustomClose);
};
mraid.expand = function(url) {
log.i("mraid.expand: " + (url === undefined) ? "(1-part)" : url);
mraid.isViewable = function() {
log.i("mraid.isViewable");
return isViewable;
};
mraid.playVideo = function(uri) {
log.i("mraid.playVideo: " + uri);
if (!uri) {
broadcastEvent(EVENTS.ERROR, "Invalid URI: " + uri, "playVideo");
return;
}
notifyNative("playVideo", uri);
};
mraid.resize = function() {
log.i("mraid.resize");
notifyNative("resize", JSON.stringify(resizeProperties));
};
mraid.storePicture = function(uri) {
log.i("mraid.storePicture: " + uri);
if (!mraid.supports(mraid.SUPPORTED_FEATURES.STOREPICTURE)) {
broadcastEvent(EVENTS.ERROR, "storePicture is not supported",
"storePicture");
return;
}
notifyNative("storePicture", uri);
};
mraid.createCalendarEvent = function(parameters) {
log.i("mraid.createCalendarEvent");
if (!mraid.supports(mraid.SUPPORTED_FEATURES.CALENDAR)) {
broadcastEvent(EVENTS.ERROR, "createCalendarEvent is not supported",
"createCalendarEvent");
return;
}
notifyNative("createCalendarEvent", JSON.stringify(parameters));
};
/**
* event dispatchers
**/
mraid.fireErrorEvent = function(message, action) {
broadcastEvent(EVENTS.ERROR, message, action);
};
mraid.fireReadyEvent = function() {
broadcastEvent(EVENTS.READY);
};
mraid.fireStateChangeEvent = function(newState) {
if (state !== newState) {
state = newState;
broadcastEvent(EVENTS.STATECHANGE, state);
}
};
mraid.fireViewableChangeEvent = function(newIsViewable) {
if (isViewable !== newIsViewable) {
isViewable = newIsViewable;
broadcastEvent(EVENTS.VIEWABLECHANGE, isViewable);
}
};
mraid.fireAudioVolumeChangeEvent = function(percentage) {
if (volumePercentage !== percentage) {
volumePercentage = volumePercentage;
broadcastEvent(EVENTS.AUDIOVOLUMECHANGE, percentage);
}
};
// TODO: VPAID
/**
* pokkt extended featuers
**/
(function() {
log.i("setting up: mraid-extensions...");
/**
* pokkt specific constants
**/
var NETWORK = mraid.NETWORK = {
OFFLINE :'offline',
WIFI :'wifi',
CELL :'cell',
UNKNOWN :'unknown'
};
mraid.SUPPORTED_FEATURES.AUDIO = "audio";
mraid.SUPPORTED_FEATURES.CAMERA = "camera";
mraid.SUPPORTED_FEATURES.NETWORK = "network";
mraid.SUPPORTED_FEATURES.SHAKE = "shake";
mraid.SUPPORTED_FEATURES.TILT = "tilt";
mraid.SUPPORTED_FEATURES.HEADING = "heading";
mraid.SUPPORTED_FEATURES.ORIENTATION = "orientation";
mraid.SUPPORTED_FEATURES.MAP = "map";
mraid.EVENTS.SHAKE = "shake";
mraid.EVENTS.TILTCHANGE = "tiltChange";
mraid.EVENTS.HEADINGCHANGE = "headingChange";
mraid.EVENTS.LOCATIONCHANGE = "locationChange";
mraid.EVENTS.NETWORKCHANGE = "networkChange";
mraid.EVENTS.KEYBOARDSTATECHANGE = "keyboardStateChange";
/**
* pokkt specific states
**/
var shakeProperties = {
"interval" : 0,
"intensity" : 0
};
var tiltProperties = {
"interval" : 0,
"intensity" : 0
};
var headingProperties = {
"interval" : 0,
"intensity" : 0
};
var tiltValues = {
"x" : 0,
"y" : 0,
"z" : 0
};
var headingValue = 0;
var currentNetwork = "";
var currentKeyboardState = 0;
/**
* pokkt specific validators
**/
mraidUtils.allValidators.setShakeProperties =
mraidUtils.allValidators.setTiltProperties =
mraidUtils.allValidators.setHeadingProperties = {
"intensity":function(value) { return !isNaN(value); },
"interval":function(value) { return !isNaN(value); }
};
mraidUtils.allValidators.setTilt = {
"x":function(value) { return !isNaN(value); },
"y":function(value) { return !isNaN(value); },
"z":function(value) { return !isNaN(value); }
};
/**
* pokkt's extended properties
**/
mraid.setShakeProperties = function(properties) {
log.i("mraid.setShakeProperties: " + properties);
if (!mraidUtils.validate(properties, "setShakeProperties")) {
log.e("validation failed!");
return;
}
shakeProperties = properties;
mraidBridge.notifyNative("setShakeProperties", JSON.stringify(properties));
};
mraid.getShakeProperties = function() {
log.i("mraid.getShakeProperties");
mraid.setTiltProperties = function(properties) {
log.i("mraid.setTiltProperties: " + properties);
if (!mraidUtils.validate(properties, "setTiltProperties")) {
log.e("validation failed!");
return;
}
tiltProperties = properties;
mraidBridge.notifyNative("setTiltProperties", JSON.stringify(properties));
};
mraid.getTiltProperties = function() {
log.i("mraid.getTiltProperties");
mraid.setHeadingProperties = function(properties) {
log.i("mraid.setHeadingProperties: " + properties);
if (!mraidUtils.validate(properties, "setHeadingProperties")) {
log.e("validation failed!");
return;
}
headingProperties = properties;
mraidBridge.notifyNative("setHeadingProperties",
JSON.stringify(properties));
};
mraid.getHeadingProperties = function() {
log.i("mraid.getHeadingProperties");
mraid.getTilt = function () {
log.i("mraid.getTilt");
tiltValues = newValue;
};
mraid.getNetwork = function () {
log.i("mraid.getNetwork");
return currentNetwork;
};
mraid.getHeading = function () {
log.i("mraid.getHeading");
return headingValue;
};
mraid.getKeyboardState = function () {
log.i("mraid.getKeyboardState");
return currentKeyboardState;
}
/**
* extended methods
**/
mraid.playAudio = function(url) {
log.i("mraid.playAudio " + url);
if (!mraid.supports(mraid.SUPPORTED_FEATURES.AUDIO)) {
mraidUtils.broadcastEvent(mraid.EVENTS.ERROR, "playAudio is not
supported", "playAudio");
return;
}
mraidBridge.notifyNative("playAudio", url);
};
mraid.openCamera = function () {
log.i("mraid.openCamera");
if (!mraid.supports(mraid.SUPPORTED_FEATURES.CAMERA)) {
mraidUtils.broadcastEvent(mraid.EVENTS.ERROR, "openCamera is not
supported", "openCamera");
return;
}
mraidBridge.notifyNative("openCamera");
}
/**
* event dispatchers
**/
mraid.fireShakeEvent = function() {
log.i("mraid.fireShakeEvent");
mraidUtils.broadcastEvent(mraid.EVENTS.SHAKE);
}
mraid.fireTiltChangeEvent = function(x, y, z) {
log.i("mraid.fireTiltChangeEvent, x: " + x + " y: " + y + " z: " + z);
tiltValues.x = x;
tiltValues.y = y;
tiltValues.z = z;
mraidUtils.broadcastEvent(mraid.EVENTS.TILTCHANGE, x, y, z);
}
mraid.fireHeadingChangeEvent = function(val) {
log.i("mraid.fireHeadingChangeEvent, val: " + val);
if (headingValue != val) {
headingValue = val;
mraidUtils.broadcastEvent(mraid.EVENTS.HEADINGCHANGE, val);
}
}
mraid.fireNetworkChangeEvent = function(network) {
log.d("mraid.fireNetworkChangeEvent: " + network);
if (currentNetwork != network) {
currentNetwork = network;
mraidUtils.broadcastEvent(mraid.EVENTS.NETWORKCHANGE, network);
}
}
mraid.fireKeyboardStateChangeEvent = function(state) {
log.d("mraid.fireKeyboardStateChangeEvent: " + state);
if (currentKeyboardState !== state) {
currentKeyboardState = state;
mraidUtils.broadcastEvent(mraid.EVENTS.KEYBOARDSTATECHANGE, state);
}
}
/**
* mraid functionalities
**/
(function() {
if (console.oldLog === undefined) {
console.oldLog = console.log;
console.log = function(log) {
if (console.oldLog !== undefined) {
console.oldLog(log);
}
var LOG_LEVEL = {
"DEBUG" : 0,
"INFO" : 1,
"WARNING" : 2,
"ERROR" : 3
};
log.d = function(msg) {
if (logLevel <= LOG_LEVEL.DEBUG) {
console.log("[DEBUG] " + msg);
}
};
log.i = function(msg) {
if (logLevel <= LOG_LEVEL.INFO) {
console.log("[INFO] " + msg);
}
};
log.w = function(msg) {
if (logLevel <= LOG_LEVEL.WARN) {
console.log("[WARN] " + msg);
}
};
log.e = function(msg) {
console.log("[ERROR] " + msg);
};
} ());
/**
* console logger
**/
(function() {
log.i("init mraid...");
/**
* globals
**/
var mraid = window.mraid = {};
/**
* constants
**/
var VERSION = "3.0";
/**
* states
**/
var supportedFeatures = {};
var orientationProperties = {
"allowOrientationChange" : true,
"forceOrientation" : DEVICE_ORIENTATIONS.NONE
};
var currentAppOrientation = {
"orientation" : DEVICE_ORIENTATIONS.NONE,
"locked" : false
};
var currentPosition = {
"x" : 0,
"y" : 0,
"width" : 0,
"height" : 0
};
var defaultPosition = {
"x" : 0,
"y" : 0,
"width" : 0,
"height" : 0
};
var expandProperties = {
"width" : 0,
"height" : 0,
"useCustomClose" : false,
"isModal" : true
};
var maxSize = {
"width" : 0,
"height" : 0
};
var screenSize = {
"width" : 0,
"height" : 0
};
var resizeProperties = {
"width" : 0,
"height" : 0,
"offsetX" : 0,
"offsetY" : 0,
"customClosePosition" : CUSTOM_CLOSE_POSITION.TOP_RIGHT,
"allowOffscreen" : true
};
var locationData = {
"lat" : 0.0,
"lon" : 0.0,
"type" : LOCATION_PROVIDER_TYPES.GPS,
"accuracy" : 0.0,
"lastfix" : 0,
"ipservice" : ""
};
var exposureProperties = {
"exposedPercentage" : 0,
"visibleRectangle" : {},
"occlusionRectangles" : null // not used in this version
};
bridge.setPlacementType = function(pt) {
placementType = pt;
};
currentPosition.x = x;
currentPosition.y = y;
currentPosition.width = width;
currentPosition.height = height;
var customClosePosition =
properties.hasOwnProperty("customClosePosition") ?
properties.customClosePosition : resizeProperties.customClosePosition;
log.d("customClosePosition " + customClosePosition);
resizeUtil.fitResizeViewOnScreen = function(properties) {
log.d("fitResizeViewOnScreen");
log.d("defaultPosition " + defaultPosition.x + " " + defaultPosition.y);
log.d("offset " + properties.offsetX + " " + properties.offsetY);
if (resizeUtil.isRectContained(maxRect, resizeRect)) {
log.d("no adjustment necessary");
return adjustments;
}
return adjustments;
};
this.add = function(func) {
var id = String(func);
if (!listeners[id]) {
listeners[id] = func;
this.count++;
}
};
this.remove = function(func) {
var id = String(func);
if (listeners[id]) {
listeners[id] = null;
delete listeners[id];
this.count--;
return true;
} else {
return false;
}
};
this.removeAll = function() {
for (var id in listeners) {
if (listeners.hasOwnProperty(id)) {
this.remove(listeners[id]);
}
}
};
this.broadcast = function(args) {
for (var id in listeners) {
if (listeners.hasOwnProperty(id)) {
listeners[id].apply(mraid, args);
}
}
};
this.toString = function() {
var out = [event, ':'];
for (var id in listeners) {
if (listeners.hasOwnProperty(id)) {
out.push('|', id, '|');
}
}
return out.join('');
};
};
/**
* validators
*
* The action parameter is a string which is the name of the setter function
which called this function
* (in other words, setExpandPropeties, setOrientationProperties, or
setResizeProperties).
* It serves both as the key to get the the appropriate set of validating
functions from the allValidators object
* as well as the action parameter of any error event that may be thrown.
*
* added location-data validation
**/
/**
* mraid properties
**/
mraid.supports = function(feature) {
log.i("mraid.supports: " + feature + " " + supportedFeatures[feature]);
var retval = supportedFeatures[feature];
if (typeof retval === "undefined") {
retval = false;
}
return retval;
};
mraid.getPlacementType = function() {
log.i("mraid.getPlacementType");
return placementType;
};
mraid.getOrientationProperties = function() {
log.i("mraid.getOrientationProperties");
mraid.setOrientationProperties = function(properties) {
log.i("mraid.setOrientationProperties...");
if (!validate(properties, "setOrientationProperties")) {
log.e("validation failed!");
return;
}
var newOrientationProperties = {};
newOrientationProperties.allowOrientationChange =
orientationProperties.allowOrientationChange,
newOrientationProperties.forceOrientation =
orientationProperties.forceOrientation;
orientationProperties.allowOrientationChange =
newOrientationProperties.allowOrientationChange;
orientationProperties.forceOrientation =
newOrientationProperties.forceOrientation;
notifyNative("setOrientationProperties",
JSON.stringify(orientationProperties));
};
mraid.getCurrentAppOrientation = function() {
log.i("mraid.getCurrentAppOrientation");
mraid.getCurrentPosition = function() {
log.i("mraid.getCurrentPosition");
var position = {
"x": currentPosition.x,
"y": currentPosition.y,
"width": currentPosition.width,
"height": currentPosition.height
};
return position;
};
mraid.getDefaultPosition = function() {
log.i("mraid.getDefaultPosition");
var position = {
"x": defaultPosition.x,
"y": defaultPosition.y,
"width": defaultPosition.width,
"height": defaultPosition.height
};
return position;
};
mraid.getState = function() {
log.i("mraid.getState: " + state);
return state;
};
mraid.getExpandProperties = function() {
log.i("mraid.getExpandProperties");
var properties = {
"width" : expandProperties.width,
"height" : expandProperties.height,
"useCustomClose" : expandProperties.useCustomClose,
"isModal" : expandProperties.isModal
};
return properties;
};
mraid.setExpandProperties = function(properties) {
log.i("mraid.setExpandProperties");
if (!validate(properties, "setExpandProperties")) {
log.e("validation failed!");
return;
}
// In MRAID v2.0, all expanded ads by definition cover the entire screen,
// so the only property that the native side has to know about is
useCustomClose.
// (That is, the width and height properties are not needed by the native
code.)
if (expandProperties.useCustomClose !== oldUseCustomClose) {
mraid.useCustomClose(properties.useCustomClose);
}
};
mraid.getMaxSize = function() {
log.i("mraid.getMaxSize: " + maxSize.width + " x " + maxSize.height);
mraid.getScreenSize = function() {
log.i("mraid.getScreenSize: " + screenSize.width + " x " +
screenSize.height);
mraid.getResizeProperties = function() {
log.i("mraid.getResizeProperties");
var properties = {
"width" : resizeProperties.width,
"height" : resizeProperties.height,
"offsetX" : resizeProperties.offsetX,
"offsetY" : resizeProperties.offsetY,
"customClosePosition" : resizeProperties.customClosePosition,
"allowOffscreen" : resizeProperties.allowOffscreen
};
return properties;
};
mraid.setResizeProperties = function(properties) {
log.i("mraid.setResizeProperties");
isResizeReady = false;
// The properties object passed into this function must contain width,
height, offsetX, offsetY.
// The remaining two properties are optional.
var rwProps = [ "width", "height", "offsetX", "offsetY" ];
for (var i = 0; i < rwProps.length; i++) {
var propname = rwProps[i];
if (!properties.hasOwnProperty(propname)) {
var message = "required property " + propname + " is missing";
log.e(message);
broadcastEvent(EVENTS.ERROR, message, "setResizeProperties");
return;
}
}
if (!validate(properties, "setResizeProperties")) {
log.e("validation failed!");
return;
}
if (!allowOffscreen) {
if (properties.width > maxSize.width || properties.height >
maxSize.height) {
var message = "Resize width or height is greater than the maxSize
width or height!";
log.e(message);
broadcastEvent(EVENTS.ERROR, message, "setResizeProperties");
return;
}
adjustments = resizeUtil.fitResizeViewOnScreen(properties);
} else if (!resizeUtil.isCloseRegionOnScreen(properties)) {
var message = "Close event region will not appear entirely onscreen!";
log.e(message);
broadcastEvent(EVENTS.ERROR, message, "setResizeProperties");
return;
}
var params = {
"width" : resizeProperties.width,
"height" : resizeProperties.height,
"offsetX" : resizeProperties.offsetX + adjustments.x,
"offsetY" : resizeProperties.offsetY + adjustments.y,
"customClosePosition" : resizeProperties.customClosePosition,
"allowOffscreen" : resizeProperties.allowOffscreen
};
notifyNative("setResizeProperties", JSON.stringify(params));
isResizeReady = true;
};
mraid.getLocation = function() {
if (!validate(locationData, "locationData")) {
log.e("invalid location data!");
return -1;
}
var data = {
"lat" : locationData.lat,
"lon" : locationData.lon,
"type" : locationData.type,
"accuracy" : locationData.accuracy,
"lastfix" : locationData.lastfix,
"ipservice" : locationData.ipservice
};
return data;
};
/**
* mraid methods
**/
mraid.getVersion = function() {
log.i("mraid.getVersion: " + VERSION);
return VERSION;
};
if (!event || !listener) {
broadcastEvent(EVENTS.ERROR, "Both event and listener are required.",
"addEventListener");
return;
}
if (!contains(event, EVENTS)) {
broadcastEvent(EVENTS.ERROR, "Unknown MRAID event: " + event,
"addEventListener");
return;
}
if (!eventListeners[event]) {
eventListeners[event] = new EventListeners(event);
}
eventListeners[event].add(listener);
};
if (!event) {
broadcastEvent(EVENTS.ERROR, "Event is required.",
"removeEventListener");
return;
}
if (!contains(event, EVENTS)) {
broadcastEvent(EVENTS.ERROR, "Unknown MRAID event: " + event,
"removeEventListener");
return;
}
if (eventListeners[event]) {
if (!listener) {
eventListeners[event].removeAll();
} else if (!eventListeners[event].remove(listener)) {
broadcastEvent(EVENTS.ERROR, "Listener not currently registered for
event.", "removeEventListener");
}
}
mraid.open = function(url) {
log.i("mraid.open: " + url);
if (!url) {
broadcastEvent(EVENTS.ERROR, "Invalid URL: " + url, "open");
return;
}
notifyNative("open", url);
};
mraid.close = function() {
log.i("mraid.close");
notifyNative("close");
};
mraid.unload = function() {
log.i("mraid.unload");
notifyNative("unload");
};
mraid.useCustomClose = function(shouldUseCustomClose) {
log.i("mraid.useCustomClose: " + shouldUseCustomClose);
expandProperties.useCustomClose = shouldUseCustomClose;
notifyNative("useCustomClose", shouldUseCustomClose);
};
mraid.expand = function(url) {
log.i("mraid.expand: " + (url === undefined) ? "(1-part)" : url);
mraid.isViewable = function() {
log.i("mraid.isViewable");
return isViewable;
};
mraid.playVideo = function(uri) {
log.i("mraid.playVideo: " + uri);
if (!uri) {
broadcastEvent(EVENTS.ERROR, "Invalid URI: " + uri, "playVideo");
return;
}
notifyNative("playVideo", uri);
};
mraid.resize = function() {
log.i("mraid.resize");
notifyNative("resize", JSON.stringify(resizeProperties));
};
mraid.storePicture = function(uri) {
log.i("mraid.storePicture: " + uri);
if (!mraid.supports(mraid.SUPPORTED_FEATURES.STOREPICTURE)) {
broadcastEvent(EVENTS.ERROR, "storePicture is not supported",
"storePicture");
return;
}
if (!uri) {
broadcastEvent(EVENTS.ERROR, "Invalid URI: " + uri, "storePicture");
return;
}
notifyNative("storePicture", uri);
};
mraid.createCalendarEvent = function(parameters) {
log.i("mraid.createCalendarEvent");
if (!mraid.supports(mraid.SUPPORTED_FEATURES.CALENDAR)) {
broadcastEvent(EVENTS.ERROR, "createCalendarEvent is not supported",
"createCalendarEvent");
return;
}
notifyNative("createCalendarEvent", JSON.stringify(parameters));
};
/**
* event dispatchers
**/
mraid.fireErrorEvent = function(message, action) {
broadcastEvent(EVENTS.ERROR, message, action);
};
mraid.fireReadyEvent = function() {
broadcastEvent(EVENTS.READY);
};
mraid.fireStateChangeEvent = function(newState) {
if (state !== newState) {
state = newState;
broadcastEvent(EVENTS.STATECHANGE, state);
}
};
mraid.fireViewableChangeEvent = function(newIsViewable) {
if (isViewable !== newIsViewable) {
isViewable = newIsViewable;
broadcastEvent(EVENTS.VIEWABLECHANGE, isViewable);
}
};
mraid.fireAudioVolumeChangeEvent = function(percentage) {
if (volumePercentage !== percentage) {
volumePercentage = volumePercentage;
broadcastEvent(EVENTS.AUDIOVOLUMECHANGE, percentage);
}
};
// TODO: VPAID
/**
* pokkt extended featuers
**/
(function() {
log.i("setting up: mraid-extensions...");
/**
* pokkt specific constants
**/
var NETWORK = mraid.NETWORK = {
OFFLINE :'offline',
WIFI :'wifi',
CELL :'cell',
UNKNOWN :'unknown'
};
mraid.SUPPORTED_FEATURES.AUDIO = "audio";
mraid.SUPPORTED_FEATURES.CAMERA = "camera";
mraid.SUPPORTED_FEATURES.NETWORK = "network";
mraid.SUPPORTED_FEATURES.SHAKE = "shake";
mraid.SUPPORTED_FEATURES.TILT = "tilt";
mraid.SUPPORTED_FEATURES.HEADING = "heading";
mraid.SUPPORTED_FEATURES.ORIENTATION = "orientation";
mraid.SUPPORTED_FEATURES.MAP = "map";
mraid.EVENTS.SHAKE = "shake";
mraid.EVENTS.TILTCHANGE = "tiltChange";
mraid.EVENTS.HEADINGCHANGE = "headingChange";
mraid.EVENTS.LOCATIONCHANGE = "locationChange";
mraid.EVENTS.NETWORKCHANGE = "networkChange";
mraid.EVENTS.KEYBOARDSTATECHANGE = "keyboardStateChange";
/**
* pokkt specific states
**/
var shakeProperties = {
"interval" : 0,
"intensity" : 0
};
var tiltProperties = {
"interval" : 0,
"intensity" : 0
};
var headingProperties = {
"interval" : 0,
"intensity" : 0
};
var tiltValues = {
"x" : 0,
"y" : 0,
"z" : 0
};
var headingValue = 0;
var currentNetwork = "";
var currentKeyboardState = 0;
/**
* pokkt specific validators
**/
mraidUtils.allValidators.setShakeProperties =
mraidUtils.allValidators.setTiltProperties =
mraidUtils.allValidators.setHeadingProperties = {
"intensity":function(value) { return !isNaN(value); },
"interval":function(value) { return !isNaN(value); }
};
mraidUtils.allValidators.setTilt = {
"x":function(value) { return !isNaN(value); },
"y":function(value) { return !isNaN(value); },
"z":function(value) { return !isNaN(value); }
};
/**
* pokkt's extended properties
**/
mraid.setShakeProperties = function(properties) {
log.i("mraid.setShakeProperties: " + properties);
if (!mraidUtils.validate(properties, "setShakeProperties")) {
log.e("validation failed!");
return;
}
shakeProperties = properties;
mraidBridge.notifyNative("setShakeProperties", JSON.stringify(properties));
};
mraid.getShakeProperties = function() {
log.i("mraid.getShakeProperties");
mraid.setTiltProperties = function(properties) {
log.i("mraid.setTiltProperties: " + properties);
if (!mraidUtils.validate(properties, "setTiltProperties")) {
log.e("validation failed!");
return;
}
tiltProperties = properties;
mraidBridge.notifyNative("setTiltProperties", JSON.stringify(properties));
};
mraid.getTiltProperties = function() {
log.i("mraid.getTiltProperties");
mraid.setHeadingProperties = function(properties) {
log.i("mraid.setHeadingProperties: " + properties);
if (!mraidUtils.validate(properties, "setHeadingProperties")) {
log.e("validation failed!");
return;
}
headingProperties = properties;
mraidBridge.notifyNative("setHeadingProperties",
JSON.stringify(properties));
};
mraid.getHeadingProperties = function() {
log.i("mraid.getHeadingProperties");
mraid.getTilt = function () {
log.i("mraid.getTilt");
tiltValues = newValue;
};
mraid.getNetwork = function () {
log.i("mraid.getNetwork");
return currentNetwork;
};
mraid.getHeading = function () {
log.i("mraid.getHeading");
return headingValue;
};
mraid.getKeyboardState = function () {
log.i("mraid.getKeyboardState");
return currentKeyboardState;
}
/**
* extended methods
**/
mraid.playAudio = function(url) {
log.i("mraid.playAudio " + url);
if (!mraid.supports(mraid.SUPPORTED_FEATURES.AUDIO)) {
mraidUtils.broadcastEvent(mraid.EVENTS.ERROR, "playAudio is not
supported", "playAudio");
return;
}
mraidBridge.notifyNative("playAudio", url);
};
mraid.openCamera = function () {
log.i("mraid.openCamera");
if (!mraid.supports(mraid.SUPPORTED_FEATURES.CAMERA)) {
mraidUtils.broadcastEvent(mraid.EVENTS.ERROR, "openCamera is not
supported", "openCamera");
return;
}
mraidBridge.notifyNative("openCamera");
}
/**
* event dispatchers
**/
mraid.fireShakeEvent = function() {
log.i("mraid.fireShakeEvent");
mraidUtils.broadcastEvent(mraid.EVENTS.SHAKE);
}
mraid.fireTiltChangeEvent = function(x, y, z) {
log.i("mraid.fireTiltChangeEvent, x: " + x + " y: " + y + " z: " + z);
tiltValues.x = x;
tiltValues.y = y;
tiltValues.z = z;
mraidUtils.broadcastEvent(mraid.EVENTS.TILTCHANGE, x, y, z);
}
mraid.fireHeadingChangeEvent = function(val) {
log.i("mraid.fireHeadingChangeEvent, val: " + val);
if (headingValue != val) {
headingValue = val;
mraidUtils.broadcastEvent(mraid.EVENTS.HEADINGCHANGE, val);
}
}
mraid.fireNetworkChangeEvent = function(network) {
log.d("mraid.fireNetworkChangeEvent: " + network);
if (currentNetwork != network) {
currentNetwork = network;
mraidUtils.broadcastEvent(mraid.EVENTS.NETWORKCHANGE, network);
}
}
mraid.fireKeyboardStateChangeEvent = function(state) {
log.d("mraid.fireKeyboardStateChangeEvent: " + state);
if (currentKeyboardState !== state) {
currentKeyboardState = state;
mraidUtils.broadcastEvent(mraid.EVENTS.KEYBOARDSTATECHANGE, state);
}
}
/**
* mraid functionalities
**/
(function() {
if (console.oldLog === undefined) {
console.oldLog = console.log;
console.log = function(log) {
if (console.oldLog !== undefined) {
console.oldLog(log);
}
var LOG_LEVEL = {
"DEBUG" : 0,
"INFO" : 1,
"WARNING" : 2,
"ERROR" : 3
};
log.d = function(msg) {
if (logLevel <= LOG_LEVEL.DEBUG) {
console.log("[DEBUG] " + msg);
}
};
log.i = function(msg) {
if (logLevel <= LOG_LEVEL.INFO) {
console.log("[INFO] " + msg);
}
};
log.w = function(msg) {
if (logLevel <= LOG_LEVEL.WARN) {
console.log("[WARN] " + msg);
}
};
log.e = function(msg) {
console.log("[ERROR] " + msg);
};
} ());
/**
* console logger
**/
(function() {
log.i("init mraid...");
/**
* globals
**/
var mraid = window.mraid = {};
/**
* constants
**/
var VERSION = "3.0";
/**
* states
**/
var supportedFeatures = {};
var orientationProperties = {
"allowOrientationChange" : true,
"forceOrientation" : DEVICE_ORIENTATIONS.NONE
};
var currentAppOrientation = {
"orientation" : DEVICE_ORIENTATIONS.NONE,
"locked" : false
};
var currentPosition = {
"x" : 0,
"y" : 0,
"width" : 0,
"height" : 0
};
var defaultPosition = {
"x" : 0,
"y" : 0,
"width" : 0,
"height" : 0
};
var expandProperties = {
"width" : 0,
"height" : 0,
"useCustomClose" : false,
"isModal" : true
};
var maxSize = {
"width" : 0,
"height" : 0
};
var screenSize = {
"width" : 0,
"height" : 0
};
var resizeProperties = {
"width" : 0,
"height" : 0,
"offsetX" : 0,
"offsetY" : 0,
"customClosePosition" : CUSTOM_CLOSE_POSITION.TOP_RIGHT,
"allowOffscreen" : true
};
var locationData = {
"lat" : 0.0,
"lon" : 0.0,
"type" : LOCATION_PROVIDER_TYPES.GPS,
"accuracy" : 0.0,
"lastfix" : 0,
"ipservice" : ""
};
var exposureProperties = {
"exposedPercentage" : 0,
"visibleRectangle" : {},
"occlusionRectangles" : null // not used in this version
};
bridge.setPlacementType = function(pt) {
placementType = pt;
};
currentPosition.x = x;
currentPosition.y = y;
currentPosition.width = width;
currentPosition.height = height;
var customClosePosition =
properties.hasOwnProperty("customClosePosition") ?
properties.customClosePosition : resizeProperties.customClosePosition;
log.d("customClosePosition " + customClosePosition);
var closeRect = { "width": 50, "height": 50 };
resizeUtil.fitResizeViewOnScreen = function(properties) {
log.d("fitResizeViewOnScreen");
log.d("defaultPosition " + defaultPosition.x + " " + defaultPosition.y);
log.d("offset " + properties.offsetX + " " + properties.offsetY);
if (resizeUtil.isRectContained(maxRect, resizeRect)) {
log.d("no adjustment necessary");
return adjustments;
}
return adjustments;
};
this.add = function(func) {
var id = String(func);
if (!listeners[id]) {
listeners[id] = func;
this.count++;
}
};
this.remove = function(func) {
var id = String(func);
if (listeners[id]) {
listeners[id] = null;
delete listeners[id];
this.count--;
return true;
} else {
return false;
}
};
this.removeAll = function() {
for (var id in listeners) {
if (listeners.hasOwnProperty(id)) {
this.remove(listeners[id]);
}
}
};
this.broadcast = function(args) {
for (var id in listeners) {
if (listeners.hasOwnProperty(id)) {
listeners[id].apply(mraid, args);
}
}
};
this.toString = function() {
var out = [event, ':'];
for (var id in listeners) {
if (listeners.hasOwnProperty(id)) {
out.push('|', id, '|');
}
}
return out.join('');
};
};
/**
* validators
*
* The action parameter is a string which is the name of the setter function
which called this function
* (in other words, setExpandPropeties, setOrientationProperties, or
setResizeProperties).
* It serves both as the key to get the the appropriate set of validating
functions from the allValidators object
* as well as the action parameter of any error event that may be thrown.
*
* added location-data validation
**/
/**
* mraid properties
**/
mraid.supports = function(feature) {
log.i("mraid.supports: " + feature + " " + supportedFeatures[feature]);
var retval = supportedFeatures[feature];
if (typeof retval === "undefined") {
retval = false;
}
return retval;
};
mraid.getPlacementType = function() {
log.i("mraid.getPlacementType");
return placementType;
};
mraid.getOrientationProperties = function() {
log.i("mraid.getOrientationProperties");
mraid.setOrientationProperties = function(properties) {
log.i("mraid.setOrientationProperties...");
if (!validate(properties, "setOrientationProperties")) {
log.e("validation failed!");
return;
}
orientationProperties.allowOrientationChange =
newOrientationProperties.allowOrientationChange;
orientationProperties.forceOrientation =
newOrientationProperties.forceOrientation;
notifyNative("setOrientationProperties",
JSON.stringify(orientationProperties));
};
mraid.getCurrentAppOrientation = function() {
log.i("mraid.getCurrentAppOrientation");
mraid.getCurrentPosition = function() {
log.i("mraid.getCurrentPosition");
var position = {
"x": currentPosition.x,
"y": currentPosition.y,
"width": currentPosition.width,
"height": currentPosition.height
};
return position;
};
mraid.getDefaultPosition = function() {
log.i("mraid.getDefaultPosition");
var position = {
"x": defaultPosition.x,
"y": defaultPosition.y,
"width": defaultPosition.width,
"height": defaultPosition.height
};
return position;
};
mraid.getState = function() {
log.i("mraid.getState: " + state);
return state;
};
mraid.getExpandProperties = function() {
log.i("mraid.getExpandProperties");
var properties = {
"width" : expandProperties.width,
"height" : expandProperties.height,
"useCustomClose" : expandProperties.useCustomClose,
"isModal" : expandProperties.isModal
};
return properties;
};
mraid.setExpandProperties = function(properties) {
log.i("mraid.setExpandProperties");
if (!validate(properties, "setExpandProperties")) {
log.e("validation failed!");
return;
}
// In MRAID v2.0, all expanded ads by definition cover the entire screen,
// so the only property that the native side has to know about is
useCustomClose.
// (That is, the width and height properties are not needed by the native
code.)
if (expandProperties.useCustomClose !== oldUseCustomClose) {
mraid.useCustomClose(properties.useCustomClose);
}
};
mraid.getMaxSize = function() {
log.i("mraid.getMaxSize: " + maxSize.width + " x " + maxSize.height);
mraid.getScreenSize = function() {
log.i("mraid.getScreenSize: " + screenSize.width + " x " +
screenSize.height);
mraid.getResizeProperties = function() {
log.i("mraid.getResizeProperties");
var properties = {
"width" : resizeProperties.width,
"height" : resizeProperties.height,
"offsetX" : resizeProperties.offsetX,
"offsetY" : resizeProperties.offsetY,
"customClosePosition" : resizeProperties.customClosePosition,
"allowOffscreen" : resizeProperties.allowOffscreen
};
return properties;
};
mraid.setResizeProperties = function(properties) {
log.i("mraid.setResizeProperties");
isResizeReady = false;
// resizeProperties contains 6 read-write properties:
// width, height, offsetX, offsetY, customClosePosition, allowOffscreen
// The properties object passed into this function must contain width,
height, offsetX, offsetY.
// The remaining two properties are optional.
var rwProps = [ "width", "height", "offsetX", "offsetY" ];
for (var i = 0; i < rwProps.length; i++) {
var propname = rwProps[i];
if (!properties.hasOwnProperty(propname)) {
var message = "required property " + propname + " is missing";
log.e(message);
broadcastEvent(EVENTS.ERROR, message, "setResizeProperties");
return;
}
}
if (!validate(properties, "setResizeProperties")) {
log.e("validation failed!");
return;
}
if (!allowOffscreen) {
if (properties.width > maxSize.width || properties.height >
maxSize.height) {
var message = "Resize width or height is greater than the maxSize
width or height!";
log.e(message);
broadcastEvent(EVENTS.ERROR, message, "setResizeProperties");
return;
}
adjustments = resizeUtil.fitResizeViewOnScreen(properties);
} else if (!resizeUtil.isCloseRegionOnScreen(properties)) {
var message = "Close event region will not appear entirely onscreen!";
log.e(message);
broadcastEvent(EVENTS.ERROR, message, "setResizeProperties");
return;
}
var params = {
"width" : resizeProperties.width,
"height" : resizeProperties.height,
"offsetX" : resizeProperties.offsetX + adjustments.x,
"offsetY" : resizeProperties.offsetY + adjustments.y,
"customClosePosition" : resizeProperties.customClosePosition,
"allowOffscreen" : resizeProperties.allowOffscreen
};
notifyNative("setResizeProperties", JSON.stringify(params));
isResizeReady = true;
};
mraid.getLocation = function() {
if (!validate(locationData, "locationData")) {
log.e("invalid location data!");
return -1;
}
var data = {
"lat" : locationData.lat,
"lon" : locationData.lon,
"type" : locationData.type,
"accuracy" : locationData.accuracy,
"lastfix" : locationData.lastfix,
"ipservice" : locationData.ipservice
};
return data;
};
/**
* mraid methods
**/
mraid.getVersion = function() {
log.i("mraid.getVersion: " + VERSION);
return VERSION;
};
if (!event || !listener) {
broadcastEvent(EVENTS.ERROR, "Both event and listener are required.",
"addEventListener");
return;
}
if (!contains(event, EVENTS)) {
broadcastEvent(EVENTS.ERROR, "Unknown MRAID event: " + event,
"addEventListener");
return;
}
if (!eventListeners[event]) {
eventListeners[event] = new EventListeners(event);
}
eventListeners[event].add(listener);
};
if (!event) {
broadcastEvent(EVENTS.ERROR, "Event is required.",
"removeEventListener");
return;
}
if (!contains(event, EVENTS)) {
broadcastEvent(EVENTS.ERROR, "Unknown MRAID event: " + event,
"removeEventListener");
return;
}
if (eventListeners[event]) {
if (!listener) {
eventListeners[event].removeAll();
} else if (!eventListeners[event].remove(listener)) {
broadcastEvent(EVENTS.ERROR, "Listener not currently registered for
event.", "removeEventListener");
}
}
mraid.open = function(url) {
log.i("mraid.open: " + url);
if (!url) {
broadcastEvent(EVENTS.ERROR, "Invalid URL: " + url, "open");
return;
}
notifyNative("open", url);
};
mraid.close = function() {
log.i("mraid.close");
notifyNative("close");
};
mraid.unload = function() {
log.i("mraid.unload");
notifyNative("unload");
};
mraid.useCustomClose = function(shouldUseCustomClose) {
log.i("mraid.useCustomClose: " + shouldUseCustomClose);
expandProperties.useCustomClose = shouldUseCustomClose;
notifyNative("useCustomClose", shouldUseCustomClose);
};
mraid.expand = function(url) {
log.i("mraid.expand: " + (url === undefined) ? "(1-part)" : url);
mraid.isViewable = function() {
log.i("mraid.isViewable");
return isViewable;
};
mraid.playVideo = function(uri) {
log.i("mraid.playVideo: " + uri);
if (!uri) {
broadcastEvent(EVENTS.ERROR, "Invalid URI: " + uri, "playVideo");
return;
}
notifyNative("playVideo", uri);
};
mraid.resize = function() {
log.i("mraid.resize");
notifyNative("resize", JSON.stringify(resizeProperties));
};
mraid.storePicture = function(uri) {
log.i("mraid.storePicture: " + uri);
if (!mraid.supports(mraid.SUPPORTED_FEATURES.STOREPICTURE)) {
broadcastEvent(EVENTS.ERROR, "storePicture is not supported",
"storePicture");
return;
}
if (!uri) {
broadcastEvent(EVENTS.ERROR, "Invalid URI: " + uri, "storePicture");
return;
}
notifyNative("storePicture", uri);
};
mraid.createCalendarEvent = function(parameters) {
log.i("mraid.createCalendarEvent");
if (!mraid.supports(mraid.SUPPORTED_FEATURES.CALENDAR)) {
broadcastEvent(EVENTS.ERROR, "createCalendarEvent is not supported",
"createCalendarEvent");
return;
}
notifyNative("createCalendarEvent", JSON.stringify(parameters));
};
/**
* event dispatchers
**/
mraid.fireErrorEvent = function(message, action) {
broadcastEvent(EVENTS.ERROR, message, action);
};
mraid.fireReadyEvent = function() {
broadcastEvent(EVENTS.READY);
};
mraid.fireStateChangeEvent = function(newState) {
if (state !== newState) {
state = newState;
broadcastEvent(EVENTS.STATECHANGE, state);
}
};
mraid.fireViewableChangeEvent = function(newIsViewable) {
if (isViewable !== newIsViewable) {
isViewable = newIsViewable;
broadcastEvent(EVENTS.VIEWABLECHANGE, isViewable);
}
};
mraid.fireAudioVolumeChangeEvent = function(percentage) {
if (volumePercentage !== percentage) {
volumePercentage = volumePercentage;
broadcastEvent(EVENTS.AUDIOVOLUMECHANGE, percentage);
}
};
// TODO: VPAID
/**
* pokkt extended featuers
**/
(function() {
log.i("setting up: mraid-extensions...");
/**
* pokkt specific constants
**/
var NETWORK = mraid.NETWORK = {
OFFLINE :'offline',
WIFI :'wifi',
CELL :'cell',
UNKNOWN :'unknown'
};
mraid.SUPPORTED_FEATURES.AUDIO = "audio";
mraid.SUPPORTED_FEATURES.CAMERA = "camera";
mraid.SUPPORTED_FEATURES.NETWORK = "network";
mraid.SUPPORTED_FEATURES.SHAKE = "shake";
mraid.SUPPORTED_FEATURES.TILT = "tilt";
mraid.SUPPORTED_FEATURES.HEADING = "heading";
mraid.SUPPORTED_FEATURES.ORIENTATION = "orientation";
mraid.SUPPORTED_FEATURES.MAP = "map";
mraid.EVENTS.SHAKE = "shake";
mraid.EVENTS.TILTCHANGE = "tiltChange";
mraid.EVENTS.HEADINGCHANGE = "headingChange";
mraid.EVENTS.LOCATIONCHANGE = "locationChange";
mraid.EVENTS.NETWORKCHANGE = "networkChange";
mraid.EVENTS.KEYBOARDSTATECHANGE = "keyboardStateChange";
/**
* pokkt specific states
**/
var shakeProperties = {
"interval" : 0,
"intensity" : 0
};
var tiltProperties = {
"interval" : 0,
"intensity" : 0
};
var headingProperties = {
"interval" : 0,
"intensity" : 0
};
var tiltValues = {
"x" : 0,
"y" : 0,
"z" : 0
};
var headingValue = 0;
var currentNetwork = "";
var currentKeyboardState = 0;
/**
* pokkt specific validators
**/
mraidUtils.allValidators.setShakeProperties =
mraidUtils.allValidators.setTiltProperties =
mraidUtils.allValidators.setHeadingProperties = {
"intensity":function(value) { return !isNaN(value); },
"interval":function(value) { return !isNaN(value); }
};
mraidUtils.allValidators.setTilt = {
"x":function(value) { return !isNaN(value); },
"y":function(value) { return !isNaN(value); },
"z":function(value) { return !isNaN(value); }
};
/**
* pokkt's extended properties
**/
mraid.setShakeProperties = function(properties) {
log.i("mraid.setShakeProperties: " + properties);
if (!mraidUtils.validate(properties, "setShakeProperties")) {
log.e("validation failed!");
return;
}
shakeProperties = properties;
mraidBridge.notifyNative("setShakeProperties", JSON.stringify(properties));
};
mraid.getShakeProperties = function() {
log.i("mraid.getShakeProperties");
mraid.setTiltProperties = function(properties) {
log.i("mraid.setTiltProperties: " + properties);
if (!mraidUtils.validate(properties, "setTiltProperties")) {
log.e("validation failed!");
return;
}
tiltProperties = properties;
mraidBridge.notifyNative("setTiltProperties", JSON.stringify(properties));
};
mraid.getTiltProperties = function() {
log.i("mraid.getTiltProperties");
mraid.setHeadingProperties = function(properties) {
log.i("mraid.setHeadingProperties: " + properties);
if (!mraidUtils.validate(properties, "setHeadingProperties")) {
log.e("validation failed!");
return;
}
headingProperties = properties;
mraidBridge.notifyNative("setHeadingProperties",
JSON.stringify(properties));
};
mraid.getHeadingProperties = function() {
log.i("mraid.getHeadingProperties");
mraid.getTilt = function () {
log.i("mraid.getTilt");
tiltValues = newValue;
};
mraid.getNetwork = function () {
log.i("mraid.getNetwork");
return currentNetwork;
};
mraid.getHeading = function () {
log.i("mraid.getHeading");
return headingValue;
};
mraid.getKeyboardState = function () {
log.i("mraid.getKeyboardState");
return currentKeyboardState;
}
/**
* extended methods
**/
mraid.playAudio = function(url) {
log.i("mraid.playAudio " + url);
if (!mraid.supports(mraid.SUPPORTED_FEATURES.AUDIO)) {
mraidUtils.broadcastEvent(mraid.EVENTS.ERROR, "playAudio is not
supported", "playAudio");
return;
}
mraidBridge.notifyNative("playAudio", url);
};
mraid.openCamera = function () {
log.i("mraid.openCamera");
if (!mraid.supports(mraid.SUPPORTED_FEATURES.CAMERA)) {
mraidUtils.broadcastEvent(mraid.EVENTS.ERROR, "openCamera is not
supported", "openCamera");
return;
}
mraidBridge.notifyNative("openCamera");
}
/**
* event dispatchers
**/
mraid.fireShakeEvent = function() {
log.i("mraid.fireShakeEvent");
mraidUtils.broadcastEvent(mraid.EVENTS.SHAKE);
}
mraid.fireTiltChangeEvent = function(x, y, z) {
log.i("mraid.fireTiltChangeEvent, x: " + x + " y: " + y + " z: " + z);
tiltValues.x = x;
tiltValues.y = y;
tiltValues.z = z;
mraidUtils.broadcastEvent(mraid.EVENTS.TILTCHANGE, x, y, z);
}
mraid.fireLocationChangeEvent = function(lat, lon, type, accuracy, lastfix,
ipservice) {
log.i("mraid.fireLocationChangeEvent, lat: " + lat + " lon: " + lon + "
type: " + type +
" accuracy: " + accuracy + " lastfix: " + lastfix +
" ipservice: " + ipservice);
mraid.fireHeadingChangeEvent = function(val) {
log.i("mraid.fireHeadingChangeEvent, val: " + val);
if (headingValue != val) {
headingValue = val;
mraidUtils.broadcastEvent(mraid.EVENTS.HEADINGCHANGE, val);
}
}
mraid.fireNetworkChangeEvent = function(network) {
log.d("mraid.fireNetworkChangeEvent: " + network);
if (currentNetwork != network) {
currentNetwork = network;
mraidUtils.broadcastEvent(mraid.EVENTS.NETWORKCHANGE, network);
}
}
mraid.fireKeyboardStateChangeEvent = function(state) {
log.d("mraid.fireKeyboardStateChangeEvent: " + state);
if (currentKeyboardState !== state) {
currentKeyboardState = state;
mraidUtils.broadcastEvent(mraid.EVENTS.KEYBOARDSTATECHANGE, state);
}
}
/**
* mraid functionalities
**/
(function() {
if (console.oldLog === undefined) {
console.oldLog = console.log;
console.log = function(log) {
if (console.oldLog !== undefined) {
console.oldLog(log);
}
var LOG_LEVEL = {
"DEBUG" : 0,
"INFO" : 1,
"WARNING" : 2,
"ERROR" : 3
};
log.d = function(msg) {
if (logLevel <= LOG_LEVEL.DEBUG) {
console.log("[DEBUG] " + msg);
}
};
log.i = function(msg) {
if (logLevel <= LOG_LEVEL.INFO) {
console.log("[INFO] " + msg);
}
};
log.w = function(msg) {
if (logLevel <= LOG_LEVEL.WARN) {
console.log("[WARN] " + msg);
}
};
log.e = function(msg) {
console.log("[ERROR] " + msg);
};
} ());
/**
* console logger
**/
(function() {
log.i("init mraid...");
/**
* globals
**/
var mraid = window.mraid = {};
/**
* states
**/
var supportedFeatures = {};
var orientationProperties = {
"allowOrientationChange" : true,
"forceOrientation" : DEVICE_ORIENTATIONS.NONE
};
var currentAppOrientation = {
"orientation" : DEVICE_ORIENTATIONS.NONE,
"locked" : false
};
var currentPosition = {
"x" : 0,
"y" : 0,
"width" : 0,
"height" : 0
};
var defaultPosition = {
"x" : 0,
"y" : 0,
"width" : 0,
"height" : 0
};
var expandProperties = {
"width" : 0,
"height" : 0,
"useCustomClose" : false,
"isModal" : true
};
var maxSize = {
"width" : 0,
"height" : 0
};
var screenSize = {
"width" : 0,
"height" : 0
};
var resizeProperties = {
"width" : 0,
"height" : 0,
"offsetX" : 0,
"offsetY" : 0,
"customClosePosition" : CUSTOM_CLOSE_POSITION.TOP_RIGHT,
"allowOffscreen" : true
};
var locationData = {
"lat" : 0.0,
"lon" : 0.0,
"type" : LOCATION_PROVIDER_TYPES.GPS,
"accuracy" : 0.0,
"lastfix" : 0,
"ipservice" : ""
};
var exposureProperties = {
"exposedPercentage" : 0,
"visibleRectangle" : {},
"occlusionRectangles" : null // not used in this version
};
bridge.setPlacementType = function(pt) {
placementType = pt;
};
var customClosePosition =
properties.hasOwnProperty("customClosePosition") ?
properties.customClosePosition : resizeProperties.customClosePosition;
log.d("customClosePosition " + customClosePosition);
resizeUtil.fitResizeViewOnScreen = function(properties) {
log.d("fitResizeViewOnScreen");
log.d("defaultPosition " + defaultPosition.x + " " + defaultPosition.y);
log.d("offset " + properties.offsetX + " " + properties.offsetY);
if (resizeUtil.isRectContained(maxRect, resizeRect)) {
log.d("no adjustment necessary");
return adjustments;
}
return adjustments;
};
this.add = function(func) {
var id = String(func);
if (!listeners[id]) {
listeners[id] = func;
this.count++;
}
};
this.remove = function(func) {
var id = String(func);
if (listeners[id]) {
listeners[id] = null;
delete listeners[id];
this.count--;
return true;
} else {
return false;
}
};
this.removeAll = function() {
for (var id in listeners) {
if (listeners.hasOwnProperty(id)) {
this.remove(listeners[id]);
}
}
};
this.broadcast = function(args) {
for (var id in listeners) {
if (listeners.hasOwnProperty(id)) {
listeners[id].apply(mraid, args);
}
}
};
this.toString = function() {
var out = [event, ':'];
for (var id in listeners) {
if (listeners.hasOwnProperty(id)) {
out.push('|', id, '|');
}
}
return out.join('');
};
};
/**
* validators
*
* The action parameter is a string which is the name of the setter function
which called this function
* (in other words, setExpandPropeties, setOrientationProperties, or
setResizeProperties).
* It serves both as the key to get the the appropriate set of validating
functions from the allValidators object
* as well as the action parameter of any error event that may be thrown.
*
* added location-data validation
**/
/**
* mraid properties
**/
mraid.supports = function(feature) {
log.i("mraid.supports: " + feature + " " + supportedFeatures[feature]);
var retval = supportedFeatures[feature];
if (typeof retval === "undefined") {
retval = false;
}
return retval;
};
mraid.getPlacementType = function() {
log.i("mraid.getPlacementType");
return placementType;
};
mraid.getOrientationProperties = function() {
log.i("mraid.getOrientationProperties");
mraid.setOrientationProperties = function(properties) {
log.i("mraid.setOrientationProperties...");
if (!validate(properties, "setOrientationProperties")) {
log.e("validation failed!");
return;
}
orientationProperties.allowOrientationChange =
newOrientationProperties.allowOrientationChange;
orientationProperties.forceOrientation =
newOrientationProperties.forceOrientation;
notifyNative("setOrientationProperties",
JSON.stringify(orientationProperties));
};
mraid.getCurrentAppOrientation = function() {
log.i("mraid.getCurrentAppOrientation");
mraid.getCurrentPosition = function() {
log.i("mraid.getCurrentPosition");
var position = {
"x": currentPosition.x,
"y": currentPosition.y,
"width": currentPosition.width,
"height": currentPosition.height
};
return position;
};
mraid.getDefaultPosition = function() {
log.i("mraid.getDefaultPosition");
var position = {
"x": defaultPosition.x,
"y": defaultPosition.y,
"width": defaultPosition.width,
"height": defaultPosition.height
};
return position;
};
mraid.getState = function() {
log.i("mraid.getState: " + state);
return state;
};
mraid.getExpandProperties = function() {
log.i("mraid.getExpandProperties");
var properties = {
"width" : expandProperties.width,
"height" : expandProperties.height,
"useCustomClose" : expandProperties.useCustomClose,
"isModal" : expandProperties.isModal
};
return properties;
};
mraid.setExpandProperties = function(properties) {
log.i("mraid.setExpandProperties");
if (!validate(properties, "setExpandProperties")) {
log.e("validation failed!");
return;
}
// In MRAID v2.0, all expanded ads by definition cover the entire screen,
// so the only property that the native side has to know about is
useCustomClose.
// (That is, the width and height properties are not needed by the native
code.)
if (expandProperties.useCustomClose !== oldUseCustomClose) {
mraid.useCustomClose(properties.useCustomClose);
}
};
mraid.getMaxSize = function() {
log.i("mraid.getMaxSize: " + maxSize.width + " x " + maxSize.height);
mraid.getScreenSize = function() {
log.i("mraid.getScreenSize: " + screenSize.width + " x " +
screenSize.height);
mraid.getResizeProperties = function() {
log.i("mraid.getResizeProperties");
var properties = {
"width" : resizeProperties.width,
"height" : resizeProperties.height,
"offsetX" : resizeProperties.offsetX,
"offsetY" : resizeProperties.offsetY,
"customClosePosition" : resizeProperties.customClosePosition,
"allowOffscreen" : resizeProperties.allowOffscreen
};
return properties;
};
mraid.setResizeProperties = function(properties) {
log.i("mraid.setResizeProperties");
isResizeReady = false;
// The properties object passed into this function must contain width,
height, offsetX, offsetY.
// The remaining two properties are optional.
var rwProps = [ "width", "height", "offsetX", "offsetY" ];
for (var i = 0; i < rwProps.length; i++) {
var propname = rwProps[i];
if (!properties.hasOwnProperty(propname)) {
var message = "required property " + propname + " is missing";
log.e(message);
broadcastEvent(EVENTS.ERROR, message, "setResizeProperties");
return;
}
}
if (!validate(properties, "setResizeProperties")) {
log.e("validation failed!");
return;
}
if (!allowOffscreen) {
if (properties.width > maxSize.width || properties.height >
maxSize.height) {
var message = "Resize width or height is greater than the maxSize
width or height!";
log.e(message);
broadcastEvent(EVENTS.ERROR, message, "setResizeProperties");
return;
}
adjustments = resizeUtil.fitResizeViewOnScreen(properties);
} else if (!resizeUtil.isCloseRegionOnScreen(properties)) {
var message = "Close event region will not appear entirely onscreen!";
log.e(message);
broadcastEvent(EVENTS.ERROR, message, "setResizeProperties");
return;
}
var params = {
"width" : resizeProperties.width,
"height" : resizeProperties.height,
"offsetX" : resizeProperties.offsetX + adjustments.x,
"offsetY" : resizeProperties.offsetY + adjustments.y,
"customClosePosition" : resizeProperties.customClosePosition,
"allowOffscreen" : resizeProperties.allowOffscreen
};
notifyNative("setResizeProperties", JSON.stringify(params));
isResizeReady = true;
};
mraid.getLocation = function() {
if (!validate(locationData, "locationData")) {
log.e("invalid location data!");
return -1;
}
var data = {
"lat" : locationData.lat,
"lon" : locationData.lon,
"type" : locationData.type,
"accuracy" : locationData.accuracy,
"lastfix" : locationData.lastfix,
"ipservice" : locationData.ipservice
};
return data;
};
/**
* mraid methods
**/
mraid.getVersion = function() {
log.i("mraid.getVersion: " + VERSION);
return VERSION;
};
if (!contains(event, EVENTS)) {
broadcastEvent(EVENTS.ERROR, "Unknown MRAID event: " + event,
"addEventListener");
return;
}
if (!eventListeners[event]) {
eventListeners[event] = new EventListeners(event);
}
eventListeners[event].add(listener);
};
if (!event) {
broadcastEvent(EVENTS.ERROR, "Event is required.",
"removeEventListener");
return;
}
if (!contains(event, EVENTS)) {
broadcastEvent(EVENTS.ERROR, "Unknown MRAID event: " + event,
"removeEventListener");
return;
}
if (eventListeners[event]) {
if (!listener) {
eventListeners[event].removeAll();
} else if (!eventListeners[event].remove(listener)) {
broadcastEvent(EVENTS.ERROR, "Listener not currently registered for
event.", "removeEventListener");
}
}
mraid.open = function(url) {
log.i("mraid.open: " + url);
if (!url) {
broadcastEvent(EVENTS.ERROR, "Invalid URL: " + url, "open");
return;
}
notifyNative("open", url);
};
mraid.close = function() {
log.i("mraid.close");
notifyNative("close");
};
mraid.unload = function() {
log.i("mraid.unload");
notifyNative("unload");
};
mraid.useCustomClose = function(shouldUseCustomClose) {
log.i("mraid.useCustomClose: " + shouldUseCustomClose);
expandProperties.useCustomClose = shouldUseCustomClose;
notifyNative("useCustomClose", shouldUseCustomClose);
};
mraid.expand = function(url) {
log.i("mraid.expand: " + (url === undefined) ? "(1-part)" : url);
mraid.isViewable = function() {
log.i("mraid.isViewable");
return isViewable;
};
mraid.playVideo = function(uri) {
log.i("mraid.playVideo: " + uri);
if (!uri) {
broadcastEvent(EVENTS.ERROR, "Invalid URI: " + uri, "playVideo");
return;
}
notifyNative("playVideo", uri);
};
mraid.resize = function() {
log.i("mraid.resize");
notifyNative("resize", JSON.stringify(resizeProperties));
};
mraid.storePicture = function(uri) {
log.i("mraid.storePicture: " + uri);
if (!mraid.supports(mraid.SUPPORTED_FEATURES.STOREPICTURE)) {
broadcastEvent(EVENTS.ERROR, "storePicture is not supported",
"storePicture");
return;
}
if (!uri) {
broadcastEvent(EVENTS.ERROR, "Invalid URI: " + uri, "storePicture");
return;
}
notifyNative("storePicture", uri);
};
mraid.createCalendarEvent = function(parameters) {
log.i("mraid.createCalendarEvent");
if (!mraid.supports(mraid.SUPPORTED_FEATURES.CALENDAR)) {
broadcastEvent(EVENTS.ERROR, "createCalendarEvent is not supported",
"createCalendarEvent");
return;
}
notifyNative("createCalendarEvent", JSON.stringify(parameters));
};
/**
* event dispatchers
**/
mraid.fireErrorEvent = function(message, action) {
broadcastEvent(EVENTS.ERROR, message, action);
};
mraid.fireReadyEvent = function() {
broadcastEvent(EVENTS.READY);
};
mraid.fireStateChangeEvent = function(newState) {
if (state !== newState) {
state = newState;
broadcastEvent(EVENTS.STATECHANGE, state);
}
};
mraid.fireViewableChangeEvent = function(newIsViewable) {
if (isViewable !== newIsViewable) {
isViewable = newIsViewable;
broadcastEvent(EVENTS.VIEWABLECHANGE, isViewable);
}
};
mraid.fireAudioVolumeChangeEvent = function(percentage) {
if (volumePercentage !== percentage) {
volumePercentage = volumePercentage;
broadcastEvent(EVENTS.AUDIOVOLUMECHANGE, percentage);
}
};
// TODO: VPAID
/**
* pokkt specific constants
**/
var NETWORK = mraid.NETWORK = {
OFFLINE :'offline',
WIFI :'wifi',
CELL :'cell',
UNKNOWN :'unknown'
};
mraid.SUPPORTED_FEATURES.AUDIO = "audio";
mraid.SUPPORTED_FEATURES.CAMERA = "camera";
mraid.SUPPORTED_FEATURES.NETWORK = "network";
mraid.SUPPORTED_FEATURES.SHAKE = "shake";
mraid.SUPPORTED_FEATURES.TILT = "tilt";
mraid.SUPPORTED_FEATURES.HEADING = "heading";
mraid.SUPPORTED_FEATURES.ORIENTATION = "orientation";
mraid.SUPPORTED_FEATURES.MAP = "map";
mraid.EVENTS.SHAKE = "shake";
mraid.EVENTS.TILTCHANGE = "tiltChange";
mraid.EVENTS.HEADINGCHANGE = "headingChange";
mraid.EVENTS.LOCATIONCHANGE = "locationChange";
mraid.EVENTS.NETWORKCHANGE = "networkChange";
mraid.EVENTS.KEYBOARDSTATECHANGE = "keyboardStateChange";
/**
* pokkt specific states
**/
var shakeProperties = {
"interval" : 0,
"intensity" : 0
};
var tiltProperties = {
"interval" : 0,
"intensity" : 0
};
var headingProperties = {
"interval" : 0,
"intensity" : 0
};
var tiltValues = {
"x" : 0,
"y" : 0,
"z" : 0
};
var headingValue = 0;
var currentNetwork = "";
var currentKeyboardState = 0;
/**
* pokkt specific validators
**/
mraidUtils.allValidators.setShakeProperties =
mraidUtils.allValidators.setTiltProperties =
mraidUtils.allValidators.setHeadingProperties = {
"intensity":function(value) { return !isNaN(value); },
"interval":function(value) { return !isNaN(value); }
};
mraidUtils.allValidators.setTilt = {
"x":function(value) { return !isNaN(value); },
"y":function(value) { return !isNaN(value); },
"z":function(value) { return !isNaN(value); }
};
/**
* pokkt's extended properties
**/
mraid.setShakeProperties = function(properties) {
log.i("mraid.setShakeProperties: " + properties);
if (!mraidUtils.validate(properties, "setShakeProperties")) {
log.e("validation failed!");
return;
}
shakeProperties = properties;
mraidBridge.notifyNative("setShakeProperties", JSON.stringify(properties));
};
mraid.getShakeProperties = function() {
log.i("mraid.getShakeProperties");
mraid.setTiltProperties = function(properties) {
log.i("mraid.setTiltProperties: " + properties);
if (!mraidUtils.validate(properties, "setTiltProperties")) {
log.e("validation failed!");
return;
}
tiltProperties = properties;
mraidBridge.notifyNative("setTiltProperties", JSON.stringify(properties));
};
mraid.getTiltProperties = function() {
log.i("mraid.getTiltProperties");
mraid.setHeadingProperties = function(properties) {
log.i("mraid.setHeadingProperties: " + properties);
if (!mraidUtils.validate(properties, "setHeadingProperties")) {
log.e("validation failed!");
return;
}
headingProperties = properties;
mraidBridge.notifyNative("setHeadingProperties",
JSON.stringify(properties));
};
mraid.getHeadingProperties = function() {
log.i("mraid.getHeadingProperties");
mraid.getTilt = function () {
log.i("mraid.getTilt");
tiltValues = newValue;
};
mraid.getNetwork = function () {
log.i("mraid.getNetwork");
return currentNetwork;
};
mraid.setNetwork = function (newValue) {
log.i("mraid.setNetwork: " + newValue);
currentNetwork = newValue;
};
mraid.getHeading = function () {
log.i("mraid.getHeading");
return headingValue;
};
mraid.getKeyboardState = function () {
log.i("mraid.getKeyboardState");
return currentKeyboardState;
}
/**
* extended methods
**/
mraid.playAudio = function(url) {
log.i("mraid.playAudio " + url);
if (!mraid.supports(mraid.SUPPORTED_FEATURES.AUDIO)) {
mraidUtils.broadcastEvent(mraid.EVENTS.ERROR, "playAudio is not
supported", "playAudio");
return;
}
mraidBridge.notifyNative("playAudio", url);
};
mraid.openCamera = function () {
log.i("mraid.openCamera");
if (!mraid.supports(mraid.SUPPORTED_FEATURES.CAMERA)) {
mraidUtils.broadcastEvent(mraid.EVENTS.ERROR, "openCamera is not
supported", "openCamera");
return;
}
mraidBridge.notifyNative("openCamera");
}
/**
* event dispatchers
**/
mraid.fireShakeEvent = function() {
log.i("mraid.fireShakeEvent");
mraidUtils.broadcastEvent(mraid.EVENTS.SHAKE);
}
mraid.fireTiltChangeEvent = function(x, y, z) {
log.i("mraid.fireTiltChangeEvent, x: " + x + " y: " + y + " z: " + z);
tiltValues.x = x;
tiltValues.y = y;
tiltValues.z = z;
mraidUtils.broadcastEvent(mraid.EVENTS.TILTCHANGE, x, y, z);
}
mraid.fireHeadingChangeEvent = function(val) {
log.i("mraid.fireHeadingChangeEvent, val: " + val);
if (headingValue != val) {
headingValue = val;
mraidUtils.broadcastEvent(mraid.EVENTS.HEADINGCHANGE, val);
}
}
mraid.fireNetworkChangeEvent = function(network) {
log.d("mraid.fireNetworkChangeEvent: " + network);
if (currentNetwork != network) {
currentNetwork = network;
mraidUtils.broadcastEvent(mraid.EVENTS.NETWORKCHANGE, network);
}
}
mraid.fireKeyboardStateChangeEvent = function(state) {
log.d("mraid.fireKeyboardStateChangeEvent: " + state);
if (currentKeyboardState !== state) {
currentKeyboardState = state;
mraidUtils.broadcastEvent(mraid.EVENTS.KEYBOARDSTATECHANGE, state);
}
}