This commit is contained in:
Nick Winter 2014-05-07 15:37:49 -07:00
commit f3c6745b29
17 changed files with 1239 additions and 829 deletions

View file

@ -0,0 +1,378 @@
// There's no reason that this file is in JavaScript instead of CoffeeScript.
// We should convert it and update the brunch config.
// If we wanted to be more robust, we could use this: https://github.com/padolsey/operative/blob/master/src/operative.js
if(typeof window !== 'undefined' || !self.importScripts)
throw "Attempt to load worker_world into main window instead of web worker.";
// Taken from https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind
// This is here for running simuations in enviroments lacking function.bind (PhantomJS mostly)
if (!Function.prototype.bind) {
Function.prototype.bind = function (oThis) {
if (typeof this !== "function") {
// closest thing possible to the ECMAScript 5 internal IsCallable function
throw new TypeError("Function.prototype.bind (Shim) - target is not callable");
}
var aArgs = Array.prototype.slice.call(arguments, 1),
fToBind = this,
fNOP = function () {},
fBound = function () {
return fToBind.apply(this instanceof fNOP && oThis
? this
: oThis,
aArgs.concat(Array.prototype.slice.call(arguments)));
};
fNOP.prototype = this.prototype;
fBound.prototype = new fNOP();
return fBound;
};
}
// assign global window so that Brunch's require (in world.js) can go into it
self.window = self;
self.workerID = "DebugWorker";
self.logLimit = 2000;
self.logsLogged = 0;
var console = {
log: function() {
if(self.logsLogged++ == self.logLimit)
self.postMessage({type: 'console-log', args: ["Log limit " + self.logLimit + " reached; shutting up."], id: self.workerID});
else if(self.logsLogged < self.logLimit) {
args = [].slice.call(arguments);
for(var i = 0; i < args.length; ++i) {
if(args[i] && args[i].constructor) {
if(args[i].constructor.className === "Thang" || args[i].isComponent)
args[i] = args[i].toString();
}
}
try {
self.postMessage({type: 'console-log', args: args, id: self.workerID});
}
catch(error) {
self.postMessage({type: 'console-log', args: ["Could not post log: " + args, error.toString(), error.stack, error.stackTrace], id: self.workerID});
}
}
}}; // so that we don't crash when debugging statements happen
console.error = console.info = console.log;
self.console = console;
// We could do way more from this: http://stackoverflow.com/questions/10653809/making-webworkers-a-safe-environment
Object.defineProperty(self, "XMLHttpRequest", {
get: function() { throw new Error("Access to XMLHttpRequest is forbidden."); },
configurable: false
});
self.transferableSupported = function transferableSupported() {
// Not in IE, even in IE 11
try {
var ab = new ArrayBuffer(1);
worker.postMessage(ab, [ab]);
return ab.byteLength == 0;
} catch(error) {
return false;
}
return false;
}
importScripts('/javascripts/world.js');
var World = self.require('lib/world/world');
var GoalManager = self.require('lib/world/GoalManager');
serializedClasses = {
"Thang": self.require('lib/world/thang'),
"Vector": self.require('lib/world/vector'),
"Rectangle": self.require('lib/world/rectangle')
}
self.getCurrentFrame = function getCurrentFrame(args) { return self.world.frames.length; };
//optimize this later
self.currentUserCodeMapCopy = {};
self.currentWorldFrame = 0;
self.maxSerializationDepth = 3;
self.stringifyValue = function(value, depth) {
var brackets, i, isArray, isObject, key, prefix, s, sep, size, v, values, _i, _j, _len, _len1, _ref, _ref1, _ref2, _ref3;
if (!value || _.isString(value)) {
return value;
}
if (_.isFunction(value)) {
if (depth === 2) {
return void 0;
} else {
return "<Function>";
}
}
if (value === this.thang && depth) {
return "<this " + value.id + ">";
}
if (depth === 2) {
if (((_ref = value.constructor) != null ? _ref.className : void 0) === "Thang") {
value = "<" + (value.type || value.spriteName) + " - " + value.id + ", " + (value.pos ? value.pos.toString() : 'non-physical') + ">";
} else {
value = value.toString();
}
return value;
}
isArray = _.isArray(value);
isObject = _.isObject(value);
if (!(isArray || isObject)) {
return value.toString();
}
brackets = isArray ? ["[", "]"] : ["{", "}"];
size = _.size(value);
if (!size) {
return brackets.join("");
}
values = [];
if (isArray) {
for (_i = 0, _len = value.length; _i < _len; _i++) {
v = value[_i];
s = this.stringifyValue(v, depth + 1);
if (s !== void 0) {
values.push("" + s);
}
}
} else {
_ref2 = (_ref1 = value.apiProperties) != null ? _ref1 : _.keys(value);
for (_j = 0, _len1 = _ref2.length; _j < _len1; _j++) {
key = _ref2[_j];
if (key[0] === "_") continue;
s = this.stringifyValue(value[key], depth + 1);
if (s !== void 0) {
values.push(key + ": " + s);
}
}
}
sep = '\n' + ((function() {
var _k, _results;
_results = [];
for (i = _k = 0; 0 <= depth ? _k < depth : _k > depth; i = 0 <= depth ? ++_k : --_k) {
_results.push(" ");
}
return _results;
})()).join('');
prefix = (_ref3 = value.constructor) != null ? _ref3.className : void 0;
if (isArray) {
if (prefix == null) {
prefix = "Array";
}
}
if (isObject) {
if (prefix == null) {
prefix = "Object";
}
}
prefix = prefix ? prefix + " " : "";
return "" + prefix + brackets[0] + sep + " " + (values.join(sep + ' ')) + sep + brackets[1];
};
var cache = {};
self.invalidateCache = function () {
cache = {};
};
self.retrieveValueFromCache = function (thangID, spellID, variableChain, frame) {
var frameCache, thangCache, spellCache;
if ((frameCache = cache[frame]) && (thangCache = frameCache[thangID]) && (spellCache = thangCache[spellID]))
return spellCache[variableChain.join()];
return undefined;
};
self.updateCache = function (thangID, spellID, variableChain, frame, value) {
var key, keys, currentObject;
keys = [frame,thangID, spellID, variableChain.join()];
currentObject = cache;
for (var i = 0, len = keys.length - 1; i < len; i++)
{
key = keys[i];
if (!(key in currentObject))
currentObject[key] = {};
currentObject = currentObject[key];
}
currentObject[keys[keys.length - 1]] = value;
};
self.retrieveValueFromFrame = function retrieveValueFromFrame(args) {
var cacheValue;
if (args.frame === self.currentWorldFrame && (cacheValue = self.retrieveValueFromCache(args.currentThangID, args.currentSpellID, args.variableChain, args.frame)))
return self.postMessage({type: 'debug-value-return', serialized: {"key": args.variableChain.join("."), "value": cacheValue}});
var retrieveProperty = function retrieveProperty(currentThangID, currentSpellID, variableChain)
{
var prop;
var value;
var keys = [];
for (var i = 0, len = variableChain.length; i < len; i++) {
prop = variableChain[i];
if (prop === "this")
{
value = self.world.thangMap[currentThangID];
}
else if (i === 0)
{
try
{
var flowStates = self.world.userCodeMap[currentThangID][currentSpellID].flow.states;
//we have to go to the second last flowState as we run the world for one additional frame
//to collect the flow
value = _.last(flowStates[flowStates.length - 2].statements).variables[prop];
}
catch (e)
{
value = undefined;
}
}
else
{
value = value[prop];
}
keys.push(prop);
if (!value) break;
var classOfValue;
if (classOfValue = serializedClasses[value.CN])
{
if (value.CN === "Thang")
{
var thang = self.world.thangMap[value.id];
value = thang || "<Thang " + value.id + " (non-existent)>"
}
else
{
value = classOfValue.deserializeFromAether(value);
}
}
}
var serializedProperty = {
"key": keys.join("."),
"value": self.stringifyValue(value,0)
};
self.updateCache(currentThangID,currentSpellID,variableChain, args.frame, serializedProperty.value);
self.postMessage({type: 'debug-value-return', serialized: serializedProperty});
};
self.enableFlowOnThangSpell(args.currentThangID, args.currentSpellID, args.userCodeMap);
self.setupWorldToRunUntilFrame(args);
self.world.loadFramesUntilFrame(
args.frame,
retrieveProperty.bind({},args.currentThangID, args.currentSpellID, args.variableChain),
self.onWorldError,
self.onWorldLoadProgress
);
};
self.enableFlowOnThangSpell = function enableFlowOnThang(thangID, spellID, userCodeMap) {
try {
if (userCodeMap[thangID][spellID].originalOptions.includeFlow === true &&
userCodeMap[thangID][spellID].originalOptions.noSerializationInFlow === true)
return;
else
{
userCodeMap[thangID][spellID].originalOptions.includeFlow = true;
userCodeMap[thangID][spellID].originalOptions.noSerializationInFlow = true;
var temporaryAether = Aether.deserialize(userCodeMap[thangID][spellID]);
temporaryAether.transpile(temporaryAether.raw);
userCodeMap[thangID][spellID] = temporaryAether.serialize();
}
}
catch (e) {
console.log("there was an error enabling flow on thang spell:" + e)
}
};
self.setupWorldToRunUntilFrame = function setupWorldToRunUntilFrame(args) {
self.postedErrors = {};
self.t0 = new Date();
self.firstWorld = args.firstWorld;
self.postedErrors = false;
self.logsLogged = 0;
var stringifiedUserCodeMap = JSON.stringify(args.userCodeMap);
var userCodeMapHasChanged = ! _.isEqual(self.currentUserCodeMapCopy, stringifiedUserCodeMap);
self.currentUserCodeMapCopy = stringifiedUserCodeMap;
if (!self.world || userCodeMapHasChanged || args.frame != self.currentWorldFrame) {
self.invalidateCache();
try {
self.world = new World(args.worldName, args.userCodeMap);
if (args.level)
self.world.loadFromLevel(args.level, true);
self.goalManager = new GoalManager(self.world);
self.goalManager.setGoals(args.goals);
self.goalManager.setCode(args.userCodeMap);
self.goalManager.worldGenerationWillBegin();
self.world.setGoalManager(self.goalManager);
}
catch (error) {
self.onWorldError(error);
return;
}
Math.random = self.world.rand.randf; // so user code is predictable
self.world.totalFrames = args.frame; //hack to work around error checking
self.currentWorldFrame = args.frame;
}
};
self.runWorldUntilFrame = function runWorldUntilFrame(args) {
self.setupWorldToRunUntilFrame(args);
self.world.loadFramesUntilFrame(args.frame, self.onWorldLoaded, self.onWorldError, self.onWorldLoadProgress);
};
self.onWorldLoaded = function onWorldLoaded() {
console.log("World loaded!");
};
self.onWorldError = function onWorldError(error) {
if(error instanceof Aether.problems.UserCodeProblem) {
if(!self.postedErrors[error.key]) {
var problem = error.serialize();
self.postMessage({type: 'user-code-problem', problem: problem});
self.postedErrors[error.key] = problem;
}
}
else {
console.log("Non-UserCodeError:", error.toString() + "\n" + error.stack || error.stackTrace);
}
/* We don't actually have the recoverable property any more; hmm
if(!self.firstWorld && !error.recoverable) {
self.abort();
return false;
}
*/
return true;
};
self.onWorldLoadProgress = function onWorldLoadProgress(progress) {
self.postMessage({type: 'world-load-progress-changed', progress: progress});
};
self.abort = function abort() {
if(self.world && self.world.name) {
console.log("About to abort:", self.world.name, typeof self.world.abort);
if(typeof self.world !== "undefined")
self.world.abort();
self.world = null;
}
self.postMessage({type: 'abort'});
};
self.reportIn = function reportIn() {
self.postMessage({type: 'reportIn'});
}
self.addEventListener('message', function(event) {
self[event.data.func](event.data.args);
});
self.postMessage({type: 'worker-initialized'});

View file

@ -22,8 +22,13 @@ module.exports = class God
@angels = []
@firstWorld = true
Backbone.Mediator.subscribe 'tome:cast-spells', @onTomeCast, @
@retriveValueFromFrame = _.throttle @retrieveValueFromFrame, 1000
Backbone.Mediator.subscribe 'tome:spell-debug-value-request', @retrieveValueFromFrame, @
@fillWorkerPool = _.throttle @fillWorkerPool, 3000, leading: false
@fillWorkerPool()
#TODO: have this as a constructor option
@debugWorker = @createDebugWorker()
@currentUserCodeMap = {}
workerCode: '/javascripts/workers/worker_world.js' #Can be a string or a function.
@ -51,6 +56,13 @@ module.exports = class God
worker.addEventListener 'message', @onWorkerMessage(worker)
worker
createDebugWorker: ->
worker = new Worker '/javascripts/workers/worker_debug.js'
worker.creationTime = new Date()
worker.addEventListener 'message', @onDebugWorkerMessage
worker
onWorkerMessage: (worker) =>
unless worker.onMessage?
worker.onMessage = (event) =>
@ -62,6 +74,18 @@ module.exports = class God
console.warn "Received strange word from God: #{event.data.type}"
worker.onMessage
onDebugWorkerMessage: (event) =>
worker = event.target
switch event.data.type
when "worker-initialized"
worker.initialized = true
when 'new-debug-world'
console.log "New Debug world!"
when 'console-log'
console.log "|" + @id + "'s " + @id + "|", event.data.args...
when 'debug-value-return'
Backbone.Mediator.publish 'god:debug-value-return', event.data.serialized
getAngel: ->
freeAngel = null
for angel in @angels
@ -113,6 +137,22 @@ module.exports = class God
goals: @goalManager?.getGoals()
}}
retrieveValueFromFrame: (args) ->
if not args.thangID or not args.spellID or not args.variableChain then return
args.frame ?= @world.age / @world.dt
@debugWorker.postMessage
func: 'retrieveValueFromFrame'
args:
worldName: @level.name
userCodeMap: @currentUserCodeMap
level: @level
firstWorld: @firstWorld
goals: @goalManager?.getGoals()
frame: args.frame
currentThangID: args.thangID
currentSpellID: args.spellID
variableChain: args.variableChain
#Coffeescript needs getters and setters.
setGoalManager: (@goalManager) =>
@ -144,6 +184,7 @@ module.exports = class God
finishBeholdingWorld: (newWorld) =>
newWorld.findFirstChangedFrame @world
@world = newWorld
@currentUserCodeMap = @filterUserCodeMapWhenFromWorld @world.userCodeMap
errorCount = (t for t in @world.thangs when t.errorsOut).length
Backbone.Mediator.publish('god:new-world-created', world: @world, firstWorld: @firstWorld, errorCount: errorCount, goalStates: @latestGoalStates, team: me.team)
for scriptNote in @world.scriptNotes
@ -154,6 +195,23 @@ module.exports = class God
unless _.find @angels, 'busy'
@spells = null # Don't hold onto old spells; memory leaks
filterUserCodeMapWhenFromWorld: (worldUserCodeMap) ->
newUserCodeMap = {}
for thangName, thang of worldUserCodeMap
newUserCodeMap[thangName] = {}
for spellName,aether of thang
shallowFilteredObject = _.pick aether, ['raw','pure','originalOptions']
newUserCodeMap[thangName][spellName] = _.cloneDeep shallowFilteredObject
newUserCodeMap[thangName][spellName] = _.defaults newUserCodeMap[thangName][spellName],
flow: {}
metrics: {}
problems:
errors: []
infos: []
warnings: []
style: {}
newUserCodeMap
getUserCodeMap: ->
userCodeMap = {}
for spellKey, spell of @spells
@ -167,6 +225,10 @@ module.exports = class God
@dead = true
Backbone.Mediator.unsubscribe('tome:cast-spells', @onTomeCast, @)
@goalManager?.destroy()
@debugWorker?.terminate()
@debugWorker?.removeEventListener 'message', @onDebugWorkerMessage
@debugWorker ?= null
@currentUserCodeMap = null
@goalManager = null
@fillWorkerPool = null
@simulateWorld = null

View file

@ -59,13 +59,13 @@ module.exports = class LevelLoader extends CocoClass
url = "/db/level/#{@levelID}/session"
url += "?team=#{@team}" if @team
@session = new LevelSession().setURL url
@supermodel.loadModel(@session, 'level_session', {cache:false})
session = new LevelSession().setURL url
@session = @supermodel.loadModel(session, 'level_session', {cache:false}).model
@session.once 'sync', -> @url = -> '/db/level.session/' + @id
if @opponentSessionID
@opponentSession = new LevelSession().setURL "/db/level_session/#{@opponentSessionID}"
@supermodel.loadModel(@opponentSession, 'opponent_session')
opponentSession = new LevelSession().setURL "/db/level_session/#{@opponentSessionID}"
@opponentSession = @supermodel.loadModel(opponentSession, 'opponent_session').model
# Supermodel (Level) Loading

View file

@ -379,7 +379,9 @@ module.exports = class SpriteParser
argsSource = argsSource.replace(/cjs(.+)\)/, '"createjs$1)"') # turns cjs.Ease.get(0.5)
args = eval "[#{argsSource}]"
if args[0]?.state?[0]?.t?.search?("shape") is 0 and not _.find(localShapes, bn: args[0].state[0].t)
shadowTween = args[0]?.search?('shape') is 0 and not _.find(localShapes, bn: args[0])
shadowTween = shadowTween or args[0]?.state?[0]?.t?.search?("shape") is 0 and not _.find(localShapes, bn: args[0].state[0].t)
if shadowTween
console.log "Skipping tween", name, argsSource, args, "from localShapes", localShapes, "presumably because it's a shadow we skipped."
return
callExpressions.push {n: name, a: args}

View file

@ -8,7 +8,6 @@ WorldScriptNote = require './world_script_note'
{now, consolidateThangs, typedArraySupport} = require './world_utils'
Component = require 'lib/world/component'
System = require 'lib/world/system'
PROGRESS_UPDATE_INTERVAL = 200
DESERIALIZATION_INTERVAL = 20
@ -107,6 +106,35 @@ module.exports = class World
loadProgressCallback? 1
loadedCallback()
loadFramesUntilFrame: (frameToLoadUntil, loadedCallback, errorCallback, loadProgressCallback) ->
return if @aborted
unless @thangs.length
console.log "Warning: loadFrames called on empty World"
t1 = now()
@t0 ?= t1
i = @frames.length
while i <= frameToLoadUntil #state is gathered at next frame
try
@getFrame(i)
++i # increment this after we have succeeded in getting the frame, otherwise we'll have to do that frame again
catch error
# Not an Aether.errors.UserCodeError; maybe we can't recover
@addError error
for error in (@unhandledRuntimeErrors ? [])
return unless errorCallback error # errorCallback tells us whether the error is recoverable
@unhandledRuntimeErrors = []
t2 = now()
if t2 - t1 > PROGRESS_UPDATE_INTERVAL
loadProgressCallback? i / @totalFrames
t1 = t2
if t2 - @t0 > 1000
console.log(' Loaded', i, 'of', frameToLoadUntil, "(+" + (t2 - @t0).toFixed(0) + "ms)")
@t0 = t2
setTimeout((=> @loadFrames(loadedCallback, errorCallback, loadProgressCallback)), 0)
return
loadProgressCallback? 1
loadedCallback()
abort: ->
@aborted = true
@ -225,7 +253,7 @@ module.exports = class World
@scriptNotes.push scriptNote
return unless @goalManager
@goalManager.submitWorldGenerationEvent(channel, event, @frames.length)
setGoalState: (goalID, status) ->
@goalManager.setGoalState(goalID, status)

View file

@ -17,7 +17,7 @@ block content
if user.id != me.id
button.btn.edit-settings-button#enter-espionage-mode 007
if user.get('jobProfile')
if user.get('jobProfile') && allowedToViewJobProfile
- var profile = user.get('jobProfile');
.job-profile-container
.job-profile-row
@ -112,7 +112,11 @@ block content
.project-image(style="background-image: url('/file/" + project.picture + "')")
p= project.name
div!= marked(project.description)
else if allowedToViewJobProfile
.public-profile-container
h2 Loading...
else
.public-profile-container
h2

View file

@ -18,7 +18,7 @@ module.exports = class ProfileView extends View
super options
if @userID is me.id
@user = me
else
else if me.isAdmin() or "employer" in me.get('permissions')
@user = User.getByID(@userID)
@user.fetch()
@listenTo @user, "sync", =>
@ -27,6 +27,7 @@ module.exports = class ProfileView extends View
getRenderData: ->
context = super()
context.user = @user
context.allowedToViewJobProfile = me.isAdmin() or "employer" in me.get('permissions')
context.myProfile = @user.id is context.me.id
context.marked = marked
context.moment = moment

View file

@ -20,6 +20,7 @@ module.exports = class EmployerSignupView extends View
"click #contract-agreement-button": "agreeToContract"
"click #create-account-button": "createAccount"
"click .login-link": "setHashToOpenModalAutomatically"
"keydown": "checkForFormSubmissionEnterPress"
constructor: (options) ->
@ -78,6 +79,9 @@ module.exports = class EmployerSignupView extends View
handleAgreementFailure: (error) ->
alert "There was an error signing the contract. Please contact team@codecombat.com with this error: #{error.responseText}"
checkForFormSubmissionEnterPress: (e) ->
if e.which is 13 then @createAccount(e)
createAccount: (e) =>
window.tracker?.trackEvent 'Finished Employer Signup'
e.stopPropagation()

View file

@ -13,6 +13,8 @@ module.exports = class DebugView extends View
subscriptions:
'god:new-world-created': 'onNewWorld'
'god:debug-value-return': 'handleDebugValue'
'tome:spell-shown': 'changeCurrentThangAndSpell'
events: {}
@ -20,12 +22,26 @@ module.exports = class DebugView extends View
super options
@ace = options.ace
@thang = options.thang
@spell = options.spell
@variableStates = {}
@globals = {Math: Math, _: _, String: String, Number: Number, Array: Array, Object: Object} # ... add more as documented
for className, klass of serializedClasses
@globals[className] = klass
for className, serializedClass of serializedClasses
@globals[className] = serializedClass
@onMouseMove = _.throttle @onMouseMove, 25
changeCurrentThangAndSpell: (thangAndSpellObject) ->
@thang = thangAndSpellObject.thang
@spell = thangAndSpellObject.spell
handleDebugValue: (returnObject) ->
{key, value} = returnObject
if @variableChain and not key is @variableChain.join(".") then return
@$el.find("code").text "#{key}: #{value}"
@$el.show().css(@pos)
afterRender: ->
super()
@ace.on "mousemove", @onMouseMove
@ -58,7 +74,8 @@ module.exports = class DebugView extends View
token = prev
start = it.getCurrentTokenColumn()
chain.unshift token.value
if token and (token.value of @variableStates or token.value is "this" or @globals[token.value])
#Highlight all tokens, so true overrides all other conditions TODO: Refactor this later
if token and (true or token.value of @variableStates or token.value is "this" or @globals[token.value])
@variableChain = chain
offsetX = e.domEvent.offsetX ? e.clientX - $(e.domEvent.target).offset().left
offsetY = e.domEvent.offsetY ? e.clientY - $(e.domEvent.target).offset().top
@ -79,8 +96,11 @@ module.exports = class DebugView extends View
update: ->
if @variableChain
{key, value} = @deserializeVariableChain @variableChain
@$el.find("code").text "#{key}: #{value}"
Backbone.Mediator.publish 'tome:spell-debug-value-request',
thangID: @thang.id
spellID: @spell.name
variableChain: @variableChain
@$el.find("code").text "Finding value..."
@$el.show().css(@pos)
else
@$el.hide()
@ -98,7 +118,6 @@ module.exports = class DebugView extends View
@hoveredProperty = if @variableChain?.length is 2 then owner: @variableChain[0], property: @variableChain[1] else {}
unless _.isEqual oldHoveredProperty, @hoveredProperty
Backbone.Mediator.publish 'tome:spell-debug-property-hovered', @hoveredProperty
updateMarker: ->
if @marker
@ace.getSession().removeMarker @marker

View file

@ -193,7 +193,7 @@ module.exports = class SpellView extends View
@createToolbarView()
createDebugView: ->
@debugView = new SpellDebugView ace: @ace, thang: @thang
@debugView = new SpellDebugView ace: @ace, thang: @thang, spell:@spell
@$el.append @debugView.render().$el.hide()
createToolbarView: ->

View file

@ -105,7 +105,8 @@ UserHandler = class UserHandler extends Handler
(req, user, callback) ->
return callback(null, req, user) unless req.body.name
nameLower = req.body.name?.toLowerCase()
# return callback(null, req, user) if nameLower is user.get('nameLower')
return callback(null, req, user) unless nameLower
return callback(null, req, user) if nameLower is user.get('nameLower') and not user.get('anonymous')
User.findOne({nameLower:nameLower,anonymous:false}).exec (err, otherUser) ->
log.error "Database error setting user name: #{err}" if err
return callback(res:'Database error.', code:500) if err

View file

@ -41,6 +41,7 @@ this.createjs = this.createjs||{};
* - all children (with the exception of DOMElement) MUST use the same spriteSheet.
*
* <h4>Example</h4>
*
* var data = {
* images: ["sprites.jpg"],
* frames: {width:50, height:50},

View file

@ -403,6 +403,7 @@ var p = SpriteStage.prototype = new createjs.Stage();
* Children also MUST have either an image or spriteSheet defined on them (unless it's a DOMElement).
*
* <h4>Example</h4>
*
* addChildAt(child1, index);
*
* You can also add multiple children, such as:

View file

@ -31,6 +31,7 @@
* files of each library and are available on the createsjs namespace directly.
*
* <h4>Example</h4>
*
* myObject.addEventListener("change", createjs.proxy(myMethod, scope));
*
* @module CreateJS
@ -240,6 +241,18 @@ var p = Event.prototype;
p.clone = function() {
return new Event(this.type, this.bubbles, this.cancelable);
};
/**
* Provides a chainable shortcut method for setting a number of properties on the instance.
*
* @method set
* @param {Object} props A generic object containing properties to copy to the instance.
* @return {Event} Returns the instance the method is called on (useful for chaining calls.)
*/
p.set = function(props) {
for (var n in props) { this[n] = props[n]; }
return this;
};
/**
* Returns a string representation of this object.
@ -862,6 +875,7 @@ this.createjs = this.createjs||{};
* should not be instantiated.
*
* <h4>Example</h4>
*
* createjs.Ticker.addEventListener("tick", handleTick);
* function handleTick(event) {
* // Actions carried out each frame
@ -937,6 +951,7 @@ var Ticker = function() {
* {{#crossLink "Ticker/setPaused"}}{{/crossLink}}.
*
* <h4>Example</h4>
*
* createjs.Ticker.addEventListener("tick", handleTick);
* function handleTick(event) {
* console.log("Paused:", event.paused, event.delta);
@ -1229,6 +1244,7 @@ var Ticker = function() {
* callback when Ticker was paused. This is no longer the case.
*
* <h4>Example</h4>
*
* createjs.Ticker.addEventListener("tick", handleTick);
* createjs.Ticker.setPaused(true);
* function handleTick(event) {
@ -1251,6 +1267,7 @@ var Ticker = function() {
* callback when Ticker was paused. This is no longer the case.
*
* <h4>Example</h4>
*
* createjs.Ticker.addEventListener("tick", handleTick);
* createjs.Ticker.setPaused(true);
* function handleTick(event) {
@ -2279,8 +2296,9 @@ this.createjs = this.createjs||{};
* Represents a point on a 2 dimensional x / y coordinate system.
*
* <h4>Example</h4>
* var point = new Point(0, 100);
*
*
* var point = new createjs.Point(0, 100);
*
* @class Point
* @param {Number} [x=0] X position.
* @param {Number} [y=0] Y position.
@ -2393,7 +2411,8 @@ this.createjs = this.createjs||{};
/**
* Represents a rectangle as defined by the points (x, y) and (x+width, y+height).
*
* @example
* <h4>Example</h4>
*
* var rect = new createjs.Rectangle(0, 0, 100, 100);
*
* @class Rectangle
@ -2789,6 +2808,7 @@ this.createjs = this.createjs||{};
* via its <code>shadow</code> property.
*
* <h4>Example</h4>
*
* myImage.shadow = new createjs.Shadow("#000000", 5, 5, 10);
*
* @class Shadow
@ -3427,6 +3447,7 @@ Command.prototype.exec = function(scope) { this.f.apply(scope, this.params); };
* context of an Easel display list.
*
* <h4>Example</h4>
*
* var g = new createjs.Graphics();
* g.setStrokeStyle(1);
* g.beginStroke(createjs.Graphics.getRGB(0,0,0));
@ -3760,7 +3781,7 @@ var p = Graphics.prototype;
/**
* Draws only the path described for this Graphics instance, skipping any non-path instructions, including fill and
* stroke descriptions. Used by <code>DisplayObject.clippingPath</code> to draw the clipping path, for example.
* stroke descriptions. Used for <code>DisplayObject.mask</code> to draw the clipping path, for example.
* @method drawAsPath
* @param {CanvasRenderingContext2D} ctx The canvas 2D context object to draw into.
**/
@ -5785,9 +5806,8 @@ var p = DisplayObject.prototype = new createjs.EventDispatcher();
};
/**
* Tests whether the display object intersects the specified local point (ie. draws a pixel with alpha > 0 at
* the specified position). This ignores the alpha, shadow and compositeOperation of the display object, and all
* transform properties including regX/Y.
* Tests whether the display object intersects the specified point in local coordinates (ie. draws a pixel with alpha > 0 at
* the specified position). This ignores the alpha, shadow, hitArea, mask, and compositeOperation of the display object.
*
* <h4>Example</h4>
*
@ -5804,7 +5824,7 @@ var p = DisplayObject.prototype = new createjs.EventDispatcher();
* local Point.
*/
p.hitTest = function(x, y) {
// TODO: update with support for .hitArea and update hitArea docs?
// TODO: update with support for .hitArea & .mask and update hitArea / mask docs?
var ctx = DisplayObject._hitTestContext;
ctx.setTransform(1, 0, 0, 1, -x, -y);
this.draw(ctx);
@ -5816,7 +5836,7 @@ var p = DisplayObject.prototype = new createjs.EventDispatcher();
};
/**
* Provides a chainable shortcut method for setting a number of properties on a DisplayObject instance.
* Provides a chainable shortcut method for setting a number of properties on the instance.
*
* <h4>Example</h4>
*
@ -5826,7 +5846,7 @@ var p = DisplayObject.prototype = new createjs.EventDispatcher();
*
* @method set
* @param {Object} props A generic object containing properties to copy to the DisplayObject instance.
* @return {DisplayObject} Returns The DisplayObject instance the method is called on (useful for chaining calls.)
* @return {DisplayObject} Returns the instance the method is called on (useful for chaining calls.)
*/
p.set = function(props) {
for (var n in props) { this[n] = props[n]; }
@ -6002,17 +6022,16 @@ var p = DisplayObject.prototype = new createjs.EventDispatcher();
/**
* @method _tick
* @param {Array} params Parameters to pass on to any listeners of the tick function. This will usually include the
* @param {Object} props Props to copy to the tick event object. This will usually include the
* properties from the {{#crossLink "Ticker"}}{{/crossLink}} "tick" event, such as `delta` and `paused`, but may
* be undefined or contain other values depending on the usage by the application.
* @protected
**/
p._tick = function(params) {
p._tick = function(props) {
// because tick can be really performance sensitive, we'll inline some of the dispatchEvent work.
var ls = this._listeners;
if (ls && ls["tick"]) {
var evt = new createjs.Event("tick");
evt.params = params;
var evt = new createjs.Event("tick").set(props);
this._dispatchEvent(evt, this, 2);
}
};
@ -6180,6 +6199,7 @@ this.createjs = this.createjs||{};
* Containers have some overhead, so you generally shouldn't create a Container to hold a single child.
*
* <h4>Example</h4>
*
* var container = new createjs.Container();
* container.addChild(bitmapInstance, shapeInstance);
* container.x = 100;
@ -6299,6 +6319,7 @@ var p = Container.prototype = new createjs.DisplayObject();
* Adds a child to the top of the display list.
*
* <h4>Example</h4>
*
* container.addChild(bitmapInstance);
*
* You can also add multiple children at once:
@ -6327,6 +6348,7 @@ var p = Container.prototype = new createjs.DisplayObject();
* setting its parent to this Container.
*
* <h4>Example</h4>
*
* addChildAt(child1, index);
*
* You can also add multiple children, such as:
@ -6364,6 +6386,7 @@ var p = Container.prototype = new createjs.DisplayObject();
* already known.
*
* <h4>Example</h4>
*
* container.removeChild(child);
*
* You can also remove multiple children:
@ -6422,6 +6445,7 @@ var p = Container.prototype = new createjs.DisplayObject();
* Removes all children from the display list.
*
* <h4>Example</h4>
*
* container.removeAlLChildren();
*
* @method removeAllChildren
@ -6435,6 +6459,7 @@ var p = Container.prototype = new createjs.DisplayObject();
* Returns the child at the specified index.
*
* <h4>Example</h4>
*
* container.getChildAt(2);
*
* @method getChildAt
@ -6483,6 +6508,7 @@ var p = Container.prototype = new createjs.DisplayObject();
* Returns the index of the specified child in the display list, or -1 if it is not in the display list.
*
* <h4>Example</h4>
*
* var index = container.getChildIndex(child);
*
* @method getChildIndex
@ -6590,6 +6616,8 @@ var p = Container.prototype = new createjs.DisplayObject();
* of visual depth, with the top-most display object at index 0. This uses shape based hit detection, and can be an
* expensive operation to run, so it is best to use it carefully. For example, if testing for objects under the
* mouse, test on tick (instead of on mousemove), and only if the mouse's position has changed.
*
* Accounts for both {{#crossLink "DisplayObject/hitArea:property"}}{{/crossLink}} and {{#crossLink "DisplayObject/mask:property"}}{{/crossLink}}.
* @method getObjectsUnderPoint
* @param {Number} x The x position in the container to test.
* @param {Number} y The y position in the container to test.
@ -6679,18 +6707,18 @@ var p = Container.prototype = new createjs.DisplayObject();
/**
* @method _tick
* @param {Array} params Parameters to pass onto the DisplayObject {{#crossLink "DisplayObject/tick"}}{{/crossLink}}
* @param {Object} props Properties to copy to the DisplayObject {{#crossLink "DisplayObject/tick"}}{{/crossLink}} event object.
* function.
* @protected
**/
p._tick = function(params) {
p._tick = function(props) {
if (this.tickChildren) {
for (var i=this.children.length-1; i>=0; i--) {
var child = this.children[i];
if (child.tickEnabled && child._tick) { child._tick(params); }
if (child.tickEnabled && child._tick) { child._tick(props); }
}
}
this.DisplayObject__tick(params);
this.DisplayObject__tick(props);
};
/**
@ -6713,8 +6741,23 @@ var p = Container.prototype = new createjs.DisplayObject();
var l = children.length;
for (var i=l-1; i>=0; i--) {
var child = children[i];
var hitArea = child.hitArea;
var hitArea = child.hitArea, mask = child.mask;
if (!child.visible || (!hitArea && !child.isVisible()) || (mouse && !child.mouseEnabled)) { continue; }
if (!hitArea && mask && mask.graphics && !mask.graphics.isEmpty()) {
var maskMtx = mask.getMatrix(mask._matrix).prependMatrix(this.getConcatenatedMatrix(mtx));
ctx.setTransform(maskMtx.a, maskMtx.b, maskMtx.c, maskMtx.d, maskMtx.tx-x, maskMtx.ty-y);
// draw the mask as a solid fill:
mask.graphics.drawAsPath(ctx);
ctx.fillStyle = "#000";
ctx.fill();
// if we don't hit the mask, then no need to keep looking at this DO:
if (!this._testHit(ctx)) { continue; }
ctx.setTransform(1, 0, 0, 1, 0, 0);
ctx.clearRect(0, 0, 2, 2);
}
// if a child container has a hitArea then we only need to check its hitArea, so we can treat it as a normal DO:
if (!hitArea && child instanceof Container) {
var result = child._getObjectsUnderPoint(x, y, arr, mouse, activeListener);
@ -7138,30 +7181,19 @@ var p = Stage.prototype = new createjs.Container();
// public methods:
/**
* Each time the update method is called, the stage will tick all descendants (see: {{#crossLink "DisplayObject/tick"}}{{/crossLink}})
* and then render the display list to the canvas. Any parameters passed to `update()` will be passed on to any
* {{#crossLink "DisplayObject/tick:event"}}{{/crossLink}} event handlers.
*
* Some time-based features in EaselJS (for example {{#crossLink "Sprite/framerate"}}{{/crossLink}} require that
* a tick event object (or equivalent) be passed as the first parameter to update(). For example:
*
* Ticker.addEventListener("tick", handleTick);
* function handleTick(evtObj) {
* // do some work here, then update the stage, passing through the event object:
* myStage.update(evtObj);
* }
* Each time the update method is called, the stage will call {{#crossLink "Stage/tick"}}{{/crossLink}}
* unless {{#crossLink "Stage/tickOnUpdate:property"}}{{/crossLink}} is set to false,
* and then render the display list to the canvas.
*
* @method update
* @param {*} [params]* Params to include when ticking descendants. The first param should usually be a tick event.
* @param {*} [params]* Params to pass to .tick() if .tickOnUpdate is true.
**/
p.update = function(params) {
if (!this.canvas) { return; }
if (this.tickOnUpdate) {
this.dispatchEvent("tickstart"); // TODO: make cancellable?
this.tickEnabled&&this._tick((arguments.length ? arguments : null));
this.dispatchEvent("tickend");
if (this.tickOnUpdate) { // update this logic in SpriteStage when necessary
this.tick.apply(this, arguments);
}
this.dispatchEvent("drawstart"); // TODO: make cancellable?
this.dispatchEvent("drawstart"); //TODO: make cancellable?
createjs.DisplayObject._snapToPixelEnabled = this.snapToPixelEnabled;
if (this.autoClear) { this.clear(); }
var ctx = this.canvas.getContext("2d");
@ -7171,6 +7203,47 @@ var p = Stage.prototype = new createjs.Container();
ctx.restore();
this.dispatchEvent("drawend");
};
/**
* Propagates a tick event through the display list. This is automatically called by {{#crossLink "Stage/update"}}{{/crossLink}}
* unless {{#crossLink "Stage/tickOnUpdate:property"}}{{/crossLink}} is set to false.
*
* Any parameters passed to `tick()` will be included as an array in the "param" property of the event object dispatched
* to {{#crossLink "DisplayObject/tick:event"}}{{/crossLink}} event handlers. Additionally, if the first parameter
* is a {{#crossLink "Ticker/tick:event"}}{{/crossLink}} event object (or has equivalent properties), then the delta,
* time, runTime, and paused properties will be copied to the event object.
*
* Some time-based features in EaselJS (for example {{#crossLink "Sprite/framerate"}}{{/crossLink}} require that
* a {{#crossLink "Ticker/tick:event"}}{{/crossLink}} event object (or equivalent) be passed as the first parameter
* to tick(). For example:
*
* Ticker.on("tick", handleTick);
* function handleTick(evtObj) {
* // do some work here, then update the stage, passing through the tick event object as the first param
* // and some custom data as the second and third param:
* myStage.update(evtObj, "hello", 2014);
* }
*
* // ...
* myDisplayObject.on("tick", handleDisplayObjectTick);
* function handleDisplayObjectTick(evt) {
* console.log(evt.params[0]); // the original tick evtObj
* console.log(evt.delta, evt.paused); // ex. "17 false"
* console.log(evt.params[1], evt.params[2]); // "hello 2014"
* }
*
* @method tick
* @param {*} [params]* Params to include when ticking descendants. The first param should usually be a tick event.
**/
p.tick = function(params) {
this.dispatchEvent("tickstart"); //TODO: make cancellable?
var args = arguments.length ? Array.prototype.slice.call(arguments,0) : null;
var evt = args&&args[0];
var props = evt&&(evt.delta != null) ? {delta:evt.delta, paused:evt.paused, time:evt.time, runTime:evt.runTime } : {};
props.params = args;
this.tickEnabled&&this._tick(props);
this.dispatchEvent("tickend");
};
/**
* Default event handler that calls the Stage {{#crossLink "Stage/update"}}{{/crossLink}} method when a {{#crossLink "DisplayObject/tick:event"}}{{/crossLink}}
@ -7263,6 +7336,7 @@ var p = Stage.prototype = new createjs.Container();
* independently of mouse move events via the optional `frequency` parameter.
*
* <h4>Example</h4>
*
* var stage = new createjs.Stage("canvasId");
* stage.enableMouseOver(10); // 10 updates per second
*
@ -7687,6 +7761,7 @@ this.createjs = this.createjs||{};
* HTML element, or a string.
*
* <h4>Example</h4>
*
* var bitmap = new createjs.Bitmap("imagePath.jpg");
*
* <strong>Notes:</strong>
@ -7924,6 +7999,7 @@ this.createjs = this.createjs||{};
* See the {{#crossLink "SpriteSheet"}}{{/crossLink}} class for more information on setting up frames and animations.
*
* <h4>Example</h4>
*
* var instance = new createjs.Sprite(spriteSheet);
* instance.gotoAndStop("frameName");
*
@ -7935,7 +8011,7 @@ this.createjs = this.createjs||{};
* @constructor
* @param {SpriteSheet} spriteSheet The SpriteSheet instance to play back. This includes the source image(s), frame
* dimensions, and frame data. See {{#crossLink "SpriteSheet"}}{{/crossLink}} for more information.
* @param {String|Number} frameOrAnimation The frame number or animation to play initially.
* @param {String|Number} [frameOrAnimation] The frame number or animation to play initially.
**/
var Sprite = function(spriteSheet, frameOrAnimation) {
this.initialize(spriteSheet, frameOrAnimation);
@ -8254,14 +8330,15 @@ var p = Sprite.prototype = new createjs.DisplayObject();
/**
* Advances the <code>currentFrame</code> if paused is not true. This is called automatically when the {{#crossLink "Stage"}}{{/crossLink}}
* ticks.
* @param {Object} props Properties to copy to the DisplayObject {{#crossLink "DisplayObject/tick"}}{{/crossLink}} event object.
* @protected
* @method _tick
**/
p._tick = function(params) {
p._tick = function(props) {
if (!this.paused) {
this.advance(params&&params[0]&&params[0].delta);
this.advance(props&&props.delta);
}
this.DisplayObject__tick(params);
this.DisplayObject__tick(props);
};
@ -8338,7 +8415,7 @@ var p = Sprite.prototype = new createjs.DisplayObject();
/**
* @method cloneProps
* @param {Text} o
* @param {Sprite} o
* @protected
**/
p.cloneProps = function(o) {
@ -8477,6 +8554,7 @@ this.createjs = this.createjs||{};
* rendering cost.
*
* <h4>Example</h4>
*
* var graphics = new createjs.Graphics().beginFill("#ff0000").drawRect(0, 0, 100, 100);
* var shape = new createjs.Shape(graphics);
*
@ -8629,6 +8707,7 @@ this.createjs = this.createjs||{};
* multiple font styles, you will need to create multiple text instances, and position them manually.
*
* <h4>Example</h4>
*
* var text = new createjs.Text("Hello World", "20px Arial", "#ff7700");
* text.x = 100;
* text.textBaseline = "alphabetic";
@ -10341,14 +10420,14 @@ var p = DOMElement.prototype = new createjs.DisplayObject();
/**
* @method _tick
* @param {Array} params Parameters to pass onto the DisplayObject {{#crossLink "DisplayObject/tick"}}{{/crossLink}}
* @param {Object} props Properties to copy to the DisplayObject {{#crossLink "DisplayObject/tick"}}{{/crossLink}} event object.
* function.
* @protected
*/
p._tick = function(params) {
p._tick = function(props) {
var stage = this.getStage();
stage&&stage.on("drawend", this._handleDrawEnd, this, true);
this.DisplayObject__tick(params);
this.DisplayObject__tick(props);
};
/**
@ -10427,6 +10506,7 @@ this.createjs = this.createjs||{};
* {{#crossLink "DisplayObject/updateCache"}}{{/crossLink}}. Note that the filters must be applied before caching.
*
* <h4>Example</h4>
*
* myInstance.filters = [
* new createjs.ColorFilter(0, 0, 0, 1, 255, 0, 0),
* new createjs.BlurFilter(5, 5, 10)
@ -11428,6 +11508,7 @@ this.createjs = this.createjs||{};
* chained calls.
*
* <h4>Example</h4>
*
* myColorMatrix.adjustHue(20).adjustBrightness(50);
*
* See {{#crossLink "Filter"}}{{/crossLink}} for an example of how to apply filters, or {{#crossLink "ColorMatrixFilter"}}{{/crossLink}}

View file

@ -27,7 +27,7 @@ this.createjs = this.createjs||{};
* @type String
* @static
**/
s.buildDate = /*date*/"Thu, 06 Mar 2014 22:58:10 GMT"; // injected by build process
s.buildDate = /*date*/"Wed, 02 Apr 2014 17:54:19 GMT"; // injected by build process
})();
/*
@ -909,24 +909,32 @@ this.createjs = this.createjs||{};
var s = AbstractLoader;
/**
* The RegExp pattern to use to parse file URIs. This supports simple file names, as well as full domain URIs with
* query strings. The resulting match is: protocol:$1 domain:$2 relativePath:$3 path:$4 file:$5 extension:$6 query:$7.
* @property FILE_PATTERN
* @type {RegExp}
* The Regular Expression used to test file URLS for an absolute path.
* @property ABSOLUTE_PATH
* @static
* @protected
* @type {RegExp}
* @since 0.4.2
*/
s.FILE_PATTERN = /^(?:(\w+:)\/{2}(\w+(?:\.\w+)*\/?)|(.{0,2}\/{1}))?([/.]*?(?:[^?]+)?\/)?((?:[^/?]+)\.(\w+))(?:\?(\S+)?)?$/;
s.ABSOLUTE_PATT = /^(?:\w+:)?\/{2}/i;
/**
* The RegExp pattern to use to parse path URIs. This supports protocols, relative files, and paths. The resulting
* match is: protocol:$1 relativePath:$2 path$3.
* @property PATH_PATTERN
* @type {RegExp}
* The Regular Expression used to test file URLS for an absolute path.
* @property RELATIVE_PATH
* @static
* @protected
* @type {RegExp}
* @since 0.4.2
*/
s.PATH_PATTERN = /^(?:(\w+:)\/{2})|(.{0,2}\/{1})?([/.]*?(?:[^?]+)?\/?)?$/;
s.RELATIVE_PATT = (/^[./]*?\//i);
/**
* The Regular Expression used to test file URLS for an extension. Note that URIs must already have the query string
* removed.
* @property EXTENSION_PATT
* @static
* @type {RegExp}
* @since 0.4.2
*/
s.EXTENSION_PATT = /\/?[^/]+\.(\w{1,5})$/i;
/**
* If the loader has completed loading. This provides a quick check, but also ensures that the different approaches
@ -1164,29 +1172,49 @@ this.createjs = this.createjs||{};
};
/**
* Parse a file URI using the {{#crossLink "AbstractLoader/FILE_PATTERN:property"}}{{/crossLink}} RegExp pattern.
* @method _parseURI
* @param {String} path The file path to parse.
* @return {Array} The matched file contents. Please see the FILE_PATTERN property for details on the return value.
* This will return null if it does not match.
* @protected
* Parse a file path to determine the information we need to work with it. Currently, PreloadJS needs to know:
* <ul>
* <li>If the path is absolute. Absolute paths start with a protocol (such as `http://`, `file://`, or
* `//networkPath`)</li>
* <li>If the path is relative. Relative paths start with `../` or `/path` (or similar)</li>
* <li>The file extension. This is determined by the filename with an extension. Query strings are dropped, and
* the file path is expected to follow the format `name.ext`.</li>
* </ul>
*
* <strong>Note:</strong> This has changed from earlier versions, which used a single, complicated Regular Expression, which
* was difficult to maintain, and over-aggressive in determining all file properties. It has been simplified to
* only pull out what it needs.
* @param path
* @returns {Object} An Object with an `absolute` and `relative` Boolean, as well as an optional 'extension` String
* property, which is the lowercase extension.
* @private
*/
p._parseURI = function(path) {
if (!path) { return null; }
return path.match(s.FILE_PATTERN);
};
var info = { absolute: false, relative:false };
if (path == null) { return info; };
/**
* Parse a file URI using the {{#crossLink "AbstractLoader/PATH_PATTERN"}}{{/crossLink}} RegExp pattern.
* @method _parsePath
* @param {String} path The file path to parse.
* @return {Array} The matched path contents. Please see the PATH_PATTERN property for details on the return value.
* This will return null if it does not match.
* @protected
*/
p._parsePath = function(path) {
if (!path) { return null; }
return path.match(s.PATH_PATTERN);
// Drop the query string
var queryIndex = path.indexOf("?");
if (queryIndex > -1) {
path = path.substr(0,queryIndex);
}
// Absolute
var match;
if (s.ABSOLUTE_PATT.test(path)) {
info.absolute = true;
// Relative
} else if (s.RELATIVE_PATT.test(path)) {
info.relative = true;
}
// Extension
if (match = path.match(s.EXTENSION_PATT)) {
info.extension = match[1].toLowerCase();
}
return info;
};
/**
@ -2593,7 +2621,7 @@ TODO: WINDOWS ISSUES
// Determine Extension, etc.
var match = this._parseURI(item.src);
if (match != null) { item.ext = match[6]; }
if (match.extension) { item.ext = match.extension; }
if (item.type == null) {
item.type = this._getTypeByExtension(item.ext);
}
@ -2602,13 +2630,13 @@ TODO: WINDOWS ISSUES
var bp = ""; // Store the generated basePath
var useBasePath = basePath || this._basePath;
var autoId = item.src;
if (match && match[1] == null && match[3] == null) {
if (!match.absolute && !match.relative) {
if (path) {
bp = path;
var pathMatch = this._parsePath(path);
var pathMatch = this._parseURI(path);
autoId = path + autoId;
// Also append basePath
if (useBasePath != null && pathMatch && pathMatch[1] == null && pathMatch[2] == null) {
if (useBasePath != null && !pathMatch.absolute && !pathMatch.relative) {
bp = useBasePath + bp;
}
} else if (useBasePath != null) {
@ -2666,8 +2694,8 @@ TODO: WINDOWS ISSUES
// Update the extension in case the type changed:
match = this._parseURI(item.src);
if (match != null && match[6] != null) {
item.ext = match[6].toLowerCase();
if (match.extension != null) {
item.ext = match.extension;
}
}
}
@ -3396,7 +3424,16 @@ this.createjs = this.createjs||{};
item.type == createjs.LoadQueue.CSS) {
this._startTagVisibility = tag.style.visibility;
tag.style.visibility = "hidden";
(document.body || document.getElementsByTagName("body")[0]).appendChild(tag);
var node = document.body || document.getElementsByTagName("body")[0];
if (node == null) {
if (item.type == createjs.LoadQueue.SVG) {
this._handleSVGError();
return;
} else {
node = document.head || document.getElementsByTagName("head");
}
}
node.appendChild(tag);
}
// Note: Previous versions didn't seem to work when we called load() for OGG tags in Firefox. Seems fixed in 15.0.1
@ -3405,6 +3442,13 @@ this.createjs = this.createjs||{};
}
};
p._handleSVGError = function() {
this._clean();
var event = new createjs.Event("error");
event.text = "SVG_NO_BODY";
this._sendError(event);
};
p._handleJSONPLoad = function(data) {
this._jsonResult = data;
};
@ -3488,8 +3532,8 @@ this.createjs = this.createjs||{};
// case createjs.LoadQueue.CSS:
//LM: We may need to remove CSS tags loaded using a LINK
tag.style.visibility = this._startTagVisibility;
(document.body || document.getElementsByTagName("body")[0]).removeChild(tag);
break;
tag.parentNode && tag.parentNode.contains(tag) && tag.parentNode.removeChild(tag);
break;
default:
}

File diff suppressed because it is too large Load diff

View file

@ -909,9 +909,10 @@ var p = Tween.prototype = new createjs.EventDispatcher();
if (!target.tweenjs_count) { return; }
var tweens = Tween._tweens;
for (var i=tweens.length-1; i>=0; i--) {
if (tweens[i]._target == target) {
tweens[i]._paused = true;
tweens.splice(i,1);
var tween = tweens[i];
if (tween._target == target) {
tween._paused = true;
tweens.splice(i, 1);
}
}
target.tweenjs_count = 0;
@ -927,7 +928,7 @@ var p = Tween.prototype = new createjs.EventDispatcher();
var tweens = Tween._tweens;
for (var i= 0, l=tweens.length; i<l; i++) {
var tween = tweens[i];
tween.paused = true;
tween._paused = true;
tween.target.tweenjs_count = 0;
}
tweens.length = 0;
@ -1376,6 +1377,7 @@ var p = Tween.prototype = new createjs.EventDispatcher();
* @return {Tween} This tween instance (for chaining calls)
*/
p.setPaused = function(value) {
if (this._paused === !!value) { return this; }
this._paused = !!value;
Tween._register(this, !value);
return this;
@ -2755,6 +2757,6 @@ this.createjs = this.createjs || {};
* @type String
* @static
**/
s.buildDate = /*date*/"Thu, 12 Dec 2013 23:37:07 GMT"; // injected by build process
s.buildDate = /*date*/"Wed, 02 Apr 2014 20:57:09 GMT"; // injected by build process
})();