package com.mopub.mobileads.resource;
public class MraidJavascript {
public static final String JAVASCRIPT_SOURCE =
"(function() {\n" +
" var isIOS = (/iphone|ipad|ipod/i).test(window.navigator.userAgent.toLowerCase());\n" +
" if (isIOS) {\n" +
" console = {};\n" +
" console.log = function(log) {\n" +
" var iframe = document.createElement('iframe');\n" +
" iframe.setAttribute('src', 'ios-log: ' + log);\n" +
" document.documentElement.appendChild(iframe);\n" +
" iframe.parentNode.removeChild(iframe);\n" +
" iframe = null;\n" +
" };\n" +
" console.debug = console.info = console.warn = console.error = console.log;\n" +
" }\n" +
"}());\n" +
"\n" +
"\n" +
"(function() {\n" +
" var mraid = window.mraid = {};\n" +
"\n" +
" //////////////////////////////////////////////////////////////////////////////////////////////////\n" +
"\n" +
" // Bridge interface to SDK\n" +
"\n" +
" var bridge = window.mraidbridge = {\n" +
" nativeSDKFiredReady: false,\n" +
" nativeCallQueue: [],\n" +
" nativeCallInFlight: false,\n" +
" lastSizeChangeProperties: null\n" +
" };\n" +
"\n" +
"\n" +
" bridge.fireChangeEvent = function(properties) {\n" +
" for (var p in properties) {\n" +
" if (properties.hasOwnProperty(p)) {\n" +
" // Change handlers defined by MRAID below\n" +
" var handler = changeHandlers[p];\n" +
" handler(properties[p]);\n" +
" }\n" +
" }\n" +
" };\n" +
"\n" +
" bridge.nativeCallComplete = function(command) {\n" +
" if (this.nativeCallQueue.length === 0) {\n" +
" this.nativeCallInFlight = false;\n" +
" return;\n" +
" }\n" +
"\n" +
" var nextCall = this.nativeCallQueue.pop();\n" +
" window.location = nextCall;\n" +
" };\n" +
"\n" +
" bridge.executeNativeCall = function(args) {\n" +
" var command = args.shift();\n" +
"\n" +
" if (!this.nativeSDKFiredReady) {\n" +
" console.log('rejecting ' + command + ' because mraid is not ready');\n" +
" bridge.notifyErrorEvent('mraid is not ready', command);\n" +
" return;\n" +
" }\n" +
"\n" +
" var call = 'mraid://' + command;\n" +
"\n" +
" var key, value;\n" +
" var isFirstArgument = true;\n" +
"\n" +
" for (var i = 0; i < args.length; i += 2) {\n" +
" key = args[i];\n" +
" value = args[i + 1];\n" +
"\n" +
" if (value === null) continue;\n" +
"\n" +
" if (isFirstArgument) {\n" +
" call += '?';\n" +
" isFirstArgument = false;\n" +
" } else {\n" +
" call += '&';\n" +
" }\n" +
"\n" +
" call += encodeURIComponent(key) + '=' + encodeURIComponent(value);\n" +
" }\n" +
"\n" +
" if (this.nativeCallInFlight) {\n" +
" this.nativeCallQueue.push(call);\n" +
" } else {\n" +
" this.nativeCallInFlight = true;\n" +
" window.location = call;\n" +
" }\n" +
" };\n" +
"\n" +
"\n" +
" bridge.setCurrentPosition = function(x, y, width, height) {\n" +
" currentPosition = {\n" +
" x: x,\n" +
" y: y,\n" +
" width: width,\n" +
" height: height\n" +
" };\n" +
" broadcastEvent(EVENTS.INFO, 'Set current position to ' + stringify(currentPosition));\n" +
" };\n" +
"\n" +
" bridge.setDefaultPosition = function(x, y, width, height) {\n" +
" defaultPosition = {\n" +
" x: x,\n" +
" y: y,\n" +
" width: width,\n" +
" height: height\n" +
" };\n" +
" broadcastEvent(EVENTS.INFO, 'Set default position to ' + stringify(defaultPosition));\n" +
" };\n" +
"\n" +
" bridge.setMaxSize = function(width, height) {\n" +
" maxSize = {\n" +
" width: width,\n" +
" height: height\n" +
" };\n" +
"\n" +
" expandProperties.width = width;\n" +
" expandProperties.height = height;\n" +
"\n" +
" broadcastEvent(EVENTS.INFO, 'Set max size to ' + stringify(maxSize));\n" +
" };\n" +
"\n" +
" bridge.setPlacementType = function(_placementType) {\n" +
" placementType = _placementType;\n" +
" broadcastEvent(EVENTS.INFO, 'Set placement type to ' + stringify(placementType));\n" +
" };\n" +
"\n" +
" bridge.setScreenSize = function(width, height) {\n" +
" screenSize = {\n" +
" width: width,\n" +
" height: height\n" +
" };\n" +
" broadcastEvent(EVENTS.INFO, 'Set screen size to ' + stringify(screenSize));\n" +
" };\n" +
"\n" +
" bridge.setState = function(_state) {\n" +
" state = _state;\n" +
" broadcastEvent(EVENTS.INFO, 'Set state to ' + stringify(state));\n" +
" broadcastEvent(EVENTS.STATECHANGE, state);\n" +
" };\n" +
"\n" +
" bridge.setIsViewable = function(_isViewable) {\n" +
" isViewable = _isViewable;\n" +
" broadcastEvent(EVENTS.INFO, 'Set isViewable to ' + stringify(isViewable));\n" +
" broadcastEvent(EVENTS.VIEWABLECHANGE, isViewable);\n" +
" };\n" +
"\n" +
" bridge.setSupports = function(sms, tel, calendar, storePicture, inlineVideo) {\n" +
" supportProperties = {\n" +
" sms: sms,\n" +
" tel: tel,\n" +
" calendar: calendar,\n" +
" storePicture: storePicture,\n" +
" inlineVideo: inlineVideo\n" +
" };\n" +
" };\n" +
"\n" +
" bridge.notifyReadyEvent = function() {\n" +
" this.nativeSDKFiredReady = true;\n" +
" broadcastEvent(EVENTS.READY);\n" +
" };\n" +
"\n" +
" bridge.notifyErrorEvent = function(message, action) {\n" +
" broadcastEvent(EVENTS.ERROR, message, action);\n" +
" };\n" +
"\n" +
" // Temporary aliases while we migrate to the new API\n" +
" bridge.fireReadyEvent = bridge.notifyReadyEvent;\n" +
" bridge.fireErrorEvent = bridge.notifyErrorEvent;\n" +
"\n" +
" bridge.notifySizeChangeEvent = function(width, height) {\n" +
" if (this.lastSizeChangeProperties &&\n" +
" width == this.lastSizeChangeProperties.width && height == this.lastSizeChangeProperties.height) {\n" +
" return;\n" +
" }\n" +
"\n" +
" this.lastSizeChangeProperties = {\n" +
" width: width,\n" +
" height: height\n" +
" };\n" +
" broadcastEvent(EVENTS.SIZECHANGE, width, height);\n" +
" };\n" +
"\n" +
" bridge.notifyStateChangeEvent = function() {\n" +
" if (state === STATES.LOADING) {\n" +
" broadcastEvent(EVENTS.INFO, 'Native SDK initialized.');\n" +
" }\n" +
"\n" +
" broadcastEvent(EVENTS.INFO, 'Set state to ' + stringify(state));\n" +
" broadcastEvent(EVENTS.STATECHANGE, state);\n" +
" };\n" +
"\n" +
" bridge.notifyViewableChangeEvent = function() {\n" +
" broadcastEvent(EVENTS.INFO, 'Set isViewable to ' + stringify(isViewable));\n" +
" broadcastEvent(EVENTS.VIEWABLECHANGE, isViewable);\n" +
" };\n" +
"\n" +
"\n" +
" // Constants. ////////////////////////////////////////////////////////////////////////////////////\n" +
"\n" +
" var VERSION = mraid.VERSION = '2.0';\n" +
"\n" +
" var STATES = mraid.STATES = {\n" +
" LOADING: 'loading',\n" +
" DEFAULT: 'default',\n" +
" EXPANDED: 'expanded',\n" +
" HIDDEN: 'hidden',\n" +
" RESIZED: 'resized'\n" +
" };\n" +
"\n" +
" var EVENTS = mraid.EVENTS = {\n" +
" ERROR: 'error',\n" +
" INFO: 'info',\n" +
" READY: 'ready',\n" +
" STATECHANGE: 'stateChange',\n" +
" VIEWABLECHANGE: 'viewableChange',\n" +
" SIZECHANGE: 'sizeChange'\n" +
" };\n" +
"\n" +
" var PLACEMENT_TYPES = mraid.PLACEMENT_TYPES = {\n" +
" UNKNOWN: 'unknown',\n" +
" INLINE: 'inline',\n" +
" INTERSTITIAL: 'interstitial'\n" +
" };\n" +
"\n" +
" // External MRAID state: may be directly or indirectly modified by the ad JS. ////////////////////\n" +
"\n" +
" // Properties which define the behavior of an expandable ad.\n" +
" var expandProperties = {\n" +
" width: false,\n" +
" height: false,\n" +
" useCustomClose: false,\n" +
" isModal: true\n" +
" };\n" +
"\n" +
" var resizeProperties = {\n" +
" width: false,\n" +
" height: false,\n" +
" offsetX: false,\n" +
" offsetY: false,\n" +
" customClosePosition: 'top-right',\n" +
" allowOffscreen: true\n" +
" };\n" +
"\n" +
" var orientationProperties = {\n" +
" allowOrientationChange: true,\n" +
" forceOrientation: \"none\"\n" +
" };\n" +
"\n" +
" var supportProperties = {\n" +
" sms: false,\n" +
" tel: false,\n" +
" calendar: false,\n" +
" storePicture: false,\n" +
" inlineVideo: false\n" +
" };\n" +
"\n" +
" // default is undefined so that notifySizeChangeEvent can track changes\n" +
" var lastSizeChangeProperties;\n" +
"\n" +
" var maxSize = {};\n" +
"\n" +
" var currentPosition = {};\n" +
"\n" +
" var defaultPosition = {};\n" +
"\n" +
" var screenSize = {};\n" +
"\n" +
" var hasSetCustomClose = false;\n" +
"\n" +
" var listeners = {};\n" +
"\n" +
" // Internal MRAID state. Modified by the native SDK. /////////////////////////////////////////////\n" +
"\n" +
" var state = STATES.LOADING;\n" +
"\n" +
" var isViewable = false;\n" +
"\n" +
" var placementType = PLACEMENT_TYPES.UNKNOWN;\n" +
"\n" +
" //////////////////////////////////////////////////////////////////////////////////////////////////\n" +
"\n" +
" var EventListeners = function(event) {\n" +
" this.event = event;\n" +
" this.count = 0;\n" +
" var listeners = {};\n" +
"\n" +
" this.add = function(func) {\n" +
" var id = String(func);\n" +
" if (!listeners[id]) {\n" +
" listeners[id] = func;\n" +
" this.count++;\n" +
" }\n" +
" };\n" +
"\n" +
" this.remove = function(func) {\n" +
" var id = String(func);\n" +
" if (listeners[id]) {\n" +
" listeners[id] = null;\n" +
" delete listeners[id];\n" +
" this.count--;\n" +
" return true;\n" +
" } else {\n" +
" return false;\n" +
" }\n" +
" };\n" +
"\n" +
" this.removeAll = function() {\n" +
" for (var id in listeners) {\n" +
" if (listeners.hasOwnProperty(id)) this.remove(listeners[id]);\n" +
" }\n" +
" };\n" +
"\n" +
" this.broadcast = function(args) {\n" +
" for (var id in listeners) {\n" +
" if (listeners.hasOwnProperty(id)) listeners[id].apply(mraid, args);\n" +
" }\n" +
" };\n" +
"\n" +
" this.toString = function() {\n" +
" var out = [event, ':'];\n" +
" for (var id in listeners) {\n" +
" if (listeners.hasOwnProperty(id)) out.push('|', id, '|');\n" +
" }\n" +
" return out.join('');\n" +
" };\n" +
" };\n" +
"\n" +
" var broadcastEvent = function() {\n" +
" var args = new Array(arguments.length);\n" +
" var l = arguments.length;\n" +
" for (var i = 0; i < l; i++) args[i] = arguments[i];\n" +
" var event = args.shift();\n" +
" if (listeners[event]) listeners[event].broadcast(args);\n" +
" };\n" +
"\n" +
" var contains = function(value, array) {\n" +
" for (var i in array) {\n" +
" if (array[i] === value) return true;\n" +
" }\n" +
" return false;\n" +
" };\n" +
"\n" +
" var clone = function(obj) {\n" +
" if (obj === null) return null;\n" +
" var f = function() {};\n" +
" f.prototype = obj;\n" +
" return new f();\n" +
" };\n" +
"\n" +
" var stringify = function(obj) {\n" +
" if (typeof obj === 'object') {\n" +
" var out = [];\n" +
" if (obj.push) {\n" +
" // Array.\n" +
" for (var p in obj) out.push(obj[p]);\n" +
" return '[' + out.join(',') + ']';\n" +
" } else {\n" +
" // Other object.\n" +
" for (var p in obj) out.push(\"'\" + p + \"': \" + obj[p]);\n" +
" return '{' + out.join(',') + '}';\n" +
" }\n" +
" } else return String(obj);\n" +
" };\n" +
"\n" +
" var trim = function(str) {\n" +
" return str.replace(/^\\s+|\\s+$/g, '');\n" +
" };\n" +
"\n" +
" // Functions that will be invoked by the native SDK whenever a \"change\" event occurs.\n" +
" var changeHandlers = {\n" +
" state: function(val) {\n" +
" if (state === STATES.LOADING) {\n" +
" broadcastEvent(EVENTS.INFO, 'Native SDK initialized.');\n" +
" }\n" +
" state = val;\n" +
" broadcastEvent(EVENTS.INFO, 'Set state to ' + stringify(val));\n" +
" broadcastEvent(EVENTS.STATECHANGE, state);\n" +
" },\n" +
"\n" +
" viewable: function(val) {\n" +
" isViewable = val;\n" +
" broadcastEvent(EVENTS.INFO, 'Set isViewable to ' + stringify(val));\n" +
" broadcastEvent(EVENTS.VIEWABLECHANGE, isViewable);\n" +
" },\n" +
"\n" +
" placementType: function(val) {\n" +
" broadcastEvent(EVENTS.INFO, 'Set placementType to ' + stringify(val));\n" +
" placementType = val;\n" +
" },\n" +
"\n" +
" sizeChange: function(val) {\n" +
" broadcastEvent(EVENTS.INFO, 'Set screenSize to ' + stringify(val));\n" +
" for (var key in val) {\n" +
" if (val.hasOwnProperty(key)) screenSize[key] = val[key];\n" +
" }\n" +
" },\n" +
"\n" +
" supports: function(val) {\n" +
" broadcastEvent(EVENTS.INFO, 'Set supports to ' + stringify(val));\n" +
" supportProperties = val;\n" +
" }\n" +
" };\n" +
"\n" +
" var validate = function(obj, validators, action, merge) {\n" +
" if (!merge) {\n" +
" // Check to see if any required properties are missing.\n" +
" if (obj === null) {\n" +
" broadcastEvent(EVENTS.ERROR, 'Required object not provided.', action);\n" +
" return false;\n" +
" } else {\n" +
" for (var i in validators) {\n" +
" if (validators.hasOwnProperty(i) && obj[i] === undefined) {\n" +
" broadcastEvent(EVENTS.ERROR, 'Object is missing required property: ' + i, action);\n" +
" return false;\n" +
" }\n" +
" }\n" +
" }\n" +
" }\n" +
"\n" +
" for (var prop in obj) {\n" +
" var validator = validators[prop];\n" +
" var value = obj[prop];\n" +
" if (validator && !validator(value)) {\n" +
" // Failed validation.\n" +
" broadcastEvent(EVENTS.ERROR, 'Value of property ' + prop + ' is invalid: ' + value, action);\n" +
" return false;\n" +
" }\n" +
" }\n" +
" return true;\n" +
" };\n" +
"\n" +
" var expandPropertyValidators = {\n" +
" useCustomClose: function(v) { return (typeof v === 'boolean'); },\n" +
" };\n" +
"\n" +
" //////////////////////////////////////////////////////////////////////////////////////////////////\n" +
"\n" +
" mraid.addEventListener = function(event, listener) {\n" +
" if (!event || !listener) {\n" +
" broadcastEvent(EVENTS.ERROR, 'Both event and listener are required.', 'addEventListener');\n" +
" } else if (!contains(event, EVENTS)) {\n" +
" broadcastEvent(EVENTS.ERROR, 'Unknown MRAID event: ' + event, 'addEventListener');\n" +
" } else {\n" +
" if (!listeners[event]) {\n" +
" listeners[event] = new EventListeners(event);\n" +
" }\n" +
" listeners[event].add(listener);\n" +
" }\n" +
" };\n" +
"\n" +
" mraid.close = function() {\n" +
" if (state === STATES.HIDDEN) {\n" +
" broadcastEvent(EVENTS.ERROR, 'Ad cannot be closed when it is already hidden.',\n" +
" 'close');\n" +
" } else bridge.executeNativeCall(['close']);\n" +
" };\n" +
"\n" +
" mraid.expand = function(URL) {\n" +
" if (!(this.getState() === STATES.DEFAULT || this.getState() === STATES.RESIZED)) {\n" +
" broadcastEvent(EVENTS.ERROR, 'Ad can only be expanded from the default or resized state.', 'expand');\n" +
" } else {\n" +
" var args = ['expand',\n" +
" 'shouldUseCustomClose', expandProperties.useCustomClose\n" +
" ];\n" +
"\n" +
" if (URL) {\n" +
" args = args.concat(['url', URL]);\n" +
" }\n" +
"\n" +
" bridge.executeNativeCall(args);\n" +
" }\n" +
" };\n" +
"\n" +
" mraid.getExpandProperties = function() {\n" +
" var properties = {\n" +
" width: expandProperties.width,\n" +
" height: expandProperties.height,\n" +
" useCustomClose: expandProperties.useCustomClose,\n" +
" isModal: expandProperties.isModal\n" +
" };\n" +
" return properties;\n" +
" };\n" +
"\n" +
"\n" +
" mraid.getCurrentPosition = function() {\n" +
" return {\n" +
" x: currentPosition.x,\n" +
" y: currentPosition.y,\n" +
" width: currentPosition.width,\n" +
" height: currentPosition.height\n" +
" };\n" +
" };\n" +
"\n" +
" mraid.getDefaultPosition = function() {\n" +
" return {\n" +
" x: defaultPosition.x,\n" +
" y: defaultPosition.y,\n" +
" width: defaultPosition.width,\n" +
" height: defaultPosition.height\n" +
" };\n" +
" };\n" +
"\n" +
" mraid.getMaxSize = function() {\n" +
" return {\n" +
" width: maxSize.width,\n" +
" height: maxSize.height\n" +
" };\n" +
" };\n" +
"\n" +
" mraid.getPlacementType = function() {\n" +
" return placementType;\n" +
" };\n" +
"\n" +
" mraid.getScreenSize = function() {\n" +
" return {\n" +
" width: screenSize.width,\n" +
" height: screenSize.height\n" +
" };\n" +
" };\n" +
"\n" +
" mraid.getState = function() {\n" +
" return state;\n" +
" };\n" +
"\n" +
" mraid.isViewable = function() {\n" +
" return isViewable;\n" +
" };\n" +
"\n" +
" mraid.getVersion = function() {\n" +
" return mraid.VERSION;\n" +
" };\n" +
"\n" +
" mraid.open = function(URL) {\n" +
" if (!URL) broadcastEvent(EVENTS.ERROR, 'URL is required.', 'open');\n" +
" else bridge.executeNativeCall(['open', 'url', URL]);\n" +
" };\n" +
"\n" +
" mraid.removeEventListener = function(event, listener) {\n" +
" if (!event) {\n" +
" broadcastEvent(EVENTS.ERROR, 'Event is required.', 'removeEventListener');\n" +
" return;\n" +
" }\n" +
"\n" +
" if (listener) {\n" +
" // If we have a valid event, we'll try to remove the listener from it.\n" +
" var success = false;\n" +
" if (listeners[event]) {\n" +
" success = listeners[event].remove(listener);\n" +
" }\n" +
"\n" +
" // If we didn't have a valid event or couldn't remove the listener from the event, broadcast an error and return early.\n" +
" if (!success) {\n" +
" broadcastEvent(EVENTS.ERROR, 'Listener not currently registered for event.', 'removeEventListener');\n" +
" return;\n" +
" }\n" +
"\n" +
" } else if (!listener && listeners[event]) {\n" +
" listeners[event].removeAll();\n" +
" }\n" +
"\n" +
" if (listeners[event] && listeners[event].count === 0) {\n" +
" listeners[event] = null;\n" +
" delete listeners[event];\n" +
" }\n" +
" };\n" +
"\n" +
" mraid.setExpandProperties = function(properties) {\n" +
" if (validate(properties, expandPropertyValidators, 'setExpandProperties', true)) {\n" +
" if (properties.hasOwnProperty('useCustomClose')) {\n" +
" expandProperties.useCustomClose = properties.useCustomClose;\n" +
" }\n" +
" }\n" +
" };\n" +
"\n" +
" mraid.useCustomClose = function(shouldUseCustomClose) {\n" +
" expandProperties.useCustomClose = shouldUseCustomClose;\n" +
" hasSetCustomClose = true;\n" +
" bridge.executeNativeCall(['usecustomclose', 'shouldUseCustomClose', shouldUseCustomClose]);\n" +
" };\n" +
"\n" +
" // MRAID 2.0 APIs ////////////////////////////////////////////////////////////////////////////////\n" +
"\n" +
" mraid.createCalendarEvent = function(parameters) {\n" +
" CalendarEventParser.initialize(parameters);\n" +
" if (CalendarEventParser.parse()) {\n" +
" bridge.executeNativeCall(CalendarEventParser.arguments);\n" +
" } else {\n" +
" broadcastEvent(EVENTS.ERROR, CalendarEventParser.errors[0], 'createCalendarEvent');\n" +
" }\n" +
" };\n" +
"\n" +
" mraid.supports = function(feature) {\n" +
" return supportProperties[feature];\n" +
" };\n" +
"\n" +
" mraid.playVideo = function(uri) {\n" +
" if (!mraid.isViewable()) {\n" +
" broadcastEvent(EVENTS.ERROR, 'playVideo cannot be called until the ad is viewable', 'playVideo');\n" +
" return;\n" +
" }\n" +
"\n" +
" if (!uri) {\n" +
" broadcastEvent(EVENTS.ERROR, 'playVideo must be called with a valid URI', 'playVideo');\n" +
" } else {\n" +
" bridge.executeNativeCall(['playVideo', 'uri', uri]);\n" +
" }\n" +
" };\n" +
"\n" +
" mraid.storePicture = function(uri) {\n" +
" if (!mraid.isViewable()) {\n" +
" broadcastEvent(EVENTS.ERROR, 'storePicture cannot be called until the ad is viewable', 'storePicture');\n" +
" return;\n" +
" }\n" +
"\n" +
" if (!uri) {\n" +
" broadcastEvent(EVENTS.ERROR, 'storePicture must be called with a valid URI', 'storePicture');\n" +
" } else {\n" +
" bridge.executeNativeCall(['storePicture', 'uri', uri]);\n" +
" }\n" +
" };\n" +
"\n" +
"\n" +
" var resizePropertyValidators = {\n" +
" width: function(v) {\n" +
" return !isNaN(v) && v > 0;\n" +
" },\n" +
" height: function(v) {\n" +
" return !isNaN(v) && v > 0;\n" +
" },\n" +
" offsetX: function(v) {\n" +
" return !isNaN(v);\n" +
" },\n" +
" offsetY: function(v) {\n" +
" return !isNaN(v);\n" +
" },\n" +
" customClosePosition: function(v) {\n" +
" return (typeof v === 'string' &&\n" +
" ['top-right', 'bottom-right', 'top-left', 'bottom-left', 'center', 'top-center', 'bottom-center'].indexOf(v) > -1);\n" +
" },\n" +
" allowOffscreen: function(v) {\n" +
" return (typeof v === 'boolean');\n" +
" }\n" +
" };\n" +
"\n" +
" mraid.setOrientationProperties = function(properties) {\n" +
"\n" +
" if (properties.hasOwnProperty('allowOrientationChange')) {\n" +
" orientationProperties.allowOrientationChange = properties.allowOrientationChange;\n" +
" }\n" +
"\n" +
" if (properties.hasOwnProperty('forceOrientation')) {\n" +
" orientationProperties.forceOrientation = properties.forceOrientation;\n" +
" }\n" +
"\n" +
" var args = ['setOrientationProperties',\n" +
" 'allowOrientationChange', orientationProperties.allowOrientationChange,\n" +
" 'forceOrientation', orientationProperties.forceOrientation\n" +
" ];\n" +
" bridge.executeNativeCall(args);\n" +
" };\n" +
"\n" +
" mraid.getOrientationProperties = function() {\n" +
" return {\n" +
" allowOrientationChange: orientationProperties.allowOrientationChange,\n" +
" forceOrientation: orientationProperties.forceOrientation\n" +
" };\n" +
" };\n" +
"\n" +
" mraid.resize = function() {\n" +
" if (!(this.getState() === STATES.DEFAULT || this.getState() === STATES.RESIZED)) {\n" +
" broadcastEvent(EVENTS.ERROR, 'Ad can only be resized from the default or resized state.', 'resize');\n" +
" } else if (!resizeProperties.width || !resizeProperties.height) {\n" +
" broadcastEvent(EVENTS.ERROR, 'Must set resize properties before calling resize()', 'resize');\n" +
" } else {\n" +
" var args = ['resize',\n" +
" 'width', resizeProperties.width,\n" +
" 'height', resizeProperties.height,\n" +
" 'offsetX', resizeProperties.offsetX || 0,\n" +
" 'offsetY', resizeProperties.offsetY || 0,\n" +
" 'customClosePosition', resizeProperties.customClosePosition,\n" +
" 'allowOffscreen', !!resizeProperties.allowOffscreen\n" +
" ];\n" +
"\n" +
" bridge.executeNativeCall(args);\n" +
" }\n" +
" };\n" +
"\n" +
" mraid.getResizeProperties = function() {\n" +
" var properties = {\n" +
" width: resizeProperties.width,\n" +
" height: resizeProperties.height,\n" +
" offsetX: resizeProperties.offsetX,\n" +
" offsetY: resizeProperties.offsetY,\n" +
" customClosePosition: resizeProperties.customClosePosition,\n" +
" allowOffscreen: resizeProperties.allowOffscreen\n" +
" };\n" +
" return properties;\n" +
" };\n" +
"\n" +
" mraid.setResizeProperties = function(properties) {\n" +
" if (validate(properties, resizePropertyValidators, 'setResizeProperties', true)) {\n" +
"\n" +
" var desiredProperties = ['width', 'height', 'offsetX', 'offsetY', 'customClosePosition', 'allowOffscreen'];\n" +
"\n" +
" var length = desiredProperties.length;\n" +
"\n" +
" for (var i = 0; i < length; i++) {\n" +
" var propname = desiredProperties[i];\n" +
" if (properties.hasOwnProperty(propname)) {\n" +
" resizeProperties[propname] = properties[propname];\n" +
" }\n" +
" }\n" +
" }\n" +
" };\n" +
"\n" +
" var CalendarEventParser = {\n" +
" initialize: function(parameters) {\n" +
" this.parameters = parameters;\n" +
" this.errors = [];\n" +
" this.arguments = ['createCalendarEvent'];\n" +
" },\n" +
"\n" +
" parse: function() {\n" +
" if (!this.parameters) {\n" +
" this.errors.push('The object passed to createCalendarEvent cannot be null.');\n" +
" } else {\n" +
" this.parseDescription();\n" +
" this.parseLocation();\n" +
" this.parseSummary();\n" +
" this.parseStartAndEndDates();\n" +
" this.parseReminder();\n" +
" this.parseRecurrence();\n" +
" this.parseTransparency();\n" +
" }\n" +
"\n" +
" var errorCount = this.errors.length;\n" +
" if (errorCount) {\n" +
" this.arguments.length = 0;\n" +
" }\n" +
"\n" +
" return (errorCount === 0);\n" +
" },\n" +
"\n" +
" parseDescription: function() {\n" +
" this._processStringValue('description');\n" +
" },\n" +
"\n" +
" parseLocation: function() {\n" +
" this._processStringValue('location');\n" +
" },\n" +
"\n" +
" parseSummary: function() {\n" +
" this._processStringValue('summary');\n" +
" },\n" +
"\n" +
" parseStartAndEndDates: function() {\n" +
" this._processDateValue('start');\n" +
" this._processDateValue('end');\n" +
" },\n" +
"\n" +
" parseReminder: function() {\n" +
" var reminder = this._getParameter('reminder');\n" +
" if (!reminder) {\n" +
" return;\n" +
" }\n" +
"\n" +
" if (reminder < 0) {\n" +
" this.arguments.push('relativeReminder');\n" +
" this.arguments.push(parseInt(reminder) / 1000);\n" +
" } else {\n" +
" this.arguments.push('absoluteReminder');\n" +
" this.arguments.push(reminder);\n" +
" }\n" +
" },\n" +
"\n" +
" parseRecurrence: function() {\n" +
" var recurrenceDict = this._getParameter('recurrence');\n" +
" if (!recurrenceDict) {\n" +
" return;\n" +
" }\n" +
"\n" +
" this.parseRecurrenceInterval(recurrenceDict);\n" +
" this.parseRecurrenceFrequency(recurrenceDict);\n" +
" this.parseRecurrenceEndDate(recurrenceDict);\n" +
" this.parseRecurrenceArrayValue(recurrenceDict, 'daysInWeek');\n" +
" this.parseRecurrenceArrayValue(recurrenceDict, 'daysInMonth');\n" +
" this.parseRecurrenceArrayValue(recurrenceDict, 'daysInYear');\n" +
" this.parseRecurrenceArrayValue(recurrenceDict, 'monthsInYear');\n" +
" },\n" +
"\n" +
" parseTransparency: function() {\n" +
" var validValues = ['opaque', 'transparent'];\n" +
"\n" +
" if (this.parameters.hasOwnProperty('transparency')) {\n" +
" var transparency = this.parameters.transparency;\n" +
" if (contains(transparency, validValues)) {\n" +
" this.arguments.push('transparency');\n" +
" this.arguments.push(transparency);\n" +
" } else {\n" +
" this.errors.push('transparency must be opaque or transparent');\n" +
" }\n" +
" }\n" +
" },\n" +
"\n" +
" parseRecurrenceArrayValue: function(recurrenceDict, kind) {\n" +
" if (recurrenceDict.hasOwnProperty(kind)) {\n" +
" var array = recurrenceDict[kind];\n" +
" if (!array || !(array instanceof Array)) {\n" +
" this.errors.push(kind + ' must be an array.');\n" +
" } else {\n" +
" var arrayStr = array.join(',');\n" +
" this.arguments.push(kind);\n" +
" this.arguments.push(arrayStr);\n" +
" }\n" +
" }\n" +
" },\n" +
"\n" +
" parseRecurrenceInterval: function(recurrenceDict) {\n" +
" if (recurrenceDict.hasOwnProperty('interval')) {\n" +
" var interval = recurrenceDict.interval;\n" +
" if (!interval) {\n" +
" this.errors.push('Recurrence interval cannot be null.');\n" +
" } else {\n" +
" this.arguments.push('interval');\n" +
" this.arguments.push(interval);\n" +
" }\n" +
" } else {\n" +
" // If a recurrence rule was specified without an interval, use a default value of 1.\n" +
" this.arguments.push('interval');\n" +
" this.arguments.push(1);\n" +
" }\n" +
" },\n" +
"\n" +
" parseRecurrenceFrequency: function(recurrenceDict) {\n" +
" if (recurrenceDict.hasOwnProperty('frequency')) {\n" +
" var frequency = recurrenceDict.frequency;\n" +
" var validFrequencies = ['daily', 'weekly', 'monthly', 'yearly'];\n" +
" if (contains(frequency, validFrequencies)) {\n" +
" this.arguments.push('frequency');\n" +
" this.arguments.push(frequency);\n" +
" } else {\n" +
" this.errors.push('Recurrence frequency must be one of: \"daily\", \"weekly\", \"monthly\", \"yearly\".');\n" +
" }\n" +
" }\n" +
" },\n" +
"\n" +
" parseRecurrenceEndDate: function(recurrenceDict) {\n" +
" var expires = recurrenceDict.expires;\n" +
"\n" +
" if (!expires) {\n" +
" return;\n" +
" }\n" +
"\n" +
" this.arguments.push('expires');\n" +
" this.arguments.push(expires);\n" +
" },\n" +
"\n" +
" _getParameter: function(key) {\n" +
" if (this.parameters.hasOwnProperty(key)) {\n" +
" return this.parameters[key];\n" +
" }\n" +
"\n" +
" return null;\n" +
" },\n" +
"\n" +
" _processStringValue: function(kind) {\n" +
" if (this.parameters.hasOwnProperty(kind)) {\n" +
" var value = this.parameters[kind];\n" +
" this.arguments.push(kind);\n" +
" this.arguments.push(value);\n" +
" }\n" +
" },\n" +
"\n" +
" _processDateValue: function(kind) {\n" +
" if (this.parameters.hasOwnProperty(kind)) {\n" +
" var dateString = this._getParameter(kind);\n" +
" this.arguments.push(kind);\n" +
" this.arguments.push(dateString);\n" +
" }\n" +
" }\n" +
" };\n" +
"}());\n";
}