Created
April 4, 2010 01:34
-
-
Save boucher/354998 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@implementation CPEvent (CPCoding) | |
- (id)initWithCoder:(CPCoder)aCoder | |
{ | |
var type = [aCoder decodeObjectForKey:CPEventTypeKey], | |
altKey = [aCoder decodeBoolForKey:CPEventAltKeyKey], | |
bubbles = [aCoder decodeBoolForKey:CPEventBubblesKey], | |
button = [aCoder decodeIntForKey:CPEventButtonKey], | |
cancelBubble = [aCoder decodeBoolForKey:CPEventCancelBubbleKey], | |
cancelable = [aCoder decodeBoolForKey:CPEventCancelableKey], | |
charCode = [aCoder decodeObjectForKey:CPEventCharCodeKey], | |
clientX = [aCoder decodeObjectForKey:CPEventClientXKey], | |
clientY = [aCoder decodeObjectForKey:CPEventClientYKey], | |
ctrlKey = [aCoder decodeBoolForKey:CPEventCtrlKeyKey], | |
eventPhase = [aCoder decodeObjectForKey:CPEventEventPhaseKey], | |
isChar = [aCoder decodeBoolForKey:CPEventIsCharKey], | |
keyCode = [aCoder decodeObjectForKey:CPEventKeyCodeKey], | |
metaKey = [aCoder decodeBoolForKey:CPEventMetaKeyKey], | |
pageX = [aCoder decodeObjectForKey:CPEventPageXKey], | |
pageY = [aCoder decodeObjectForKey:CPEventPageYKey], | |
screenX = [aCoder decodeObjectForKey:CPEventScreenXKey], | |
screenY = [aCoder decodeObjectForKey:CPEventScreenYKey], | |
shiftKey = [aCoder decodeBoolForKey:CPEventShiftKey], | |
timeStamp = [aCoder decodeObjectForKey:CPEventTimeStampKey], | |
which = [aCoder decodeObjectForKey:CPEventWhichKey], | |
scale = [aCoder decodeObjectForKey:CPEventScaleKey], | |
rotation = [aCoder decodeObjectForKey:CPEventRotationKey], | |
nativeEvent; | |
if ([aCoder containsValueForKey:CPEventCurrentTargetKey]) | |
var currentTarget = getElementFromXPath([aCoder decodeObjectForKey:CPEventCurrentTargetKey], recorderWindow.document); | |
if ([aCoder containsValueForKey:CPEventExplicitOriginalTargeyKey]) | |
var explicitOriginalTarget = getElementFromXPath([aCoder decodeObjectForKey:CPEventExplicitOriginalTargeyKey], recorderWindow.document); | |
if ([aCoder containsValueForKey:CPEventOriginalTargetKey]) | |
var originalTarget = getElementFromXPath([aCoder decodeObjectForKey:CPEventOriginalTargetKey], recorderWindow.document); | |
if ([aCoder containsValueForKey:CPEventRelatedTargetKey]) | |
var relatedTarget = getElementFromXPath([aCoder decodeObjectForKey:CPEventRelatedTargetKey], recorderWindow.document); | |
if ([aCoder containsValueForKey:CPEventTargetKey]) | |
var target = getElementFromXPath([aCoder decodeObjectForKey:CPEventTargetKey], recorderWindow.document); | |
if ([aCoder containsValueForKey:CPEventTouchesKey]) | |
var touches = touchListFromTouchEventArray([aCoder decodeObjectForKey:CPEventTouchesKey]); | |
if ([aCoder containsValueForKey:CPEventTargetTouchesKey]) | |
var targetTouches = touchListFromTouchEventArray([aCoder decodeObjectForKey:CPEventTargetTouchesKey]); | |
if ([aCoder containsValueForKey:CPEventChangedTouchesKey]) | |
var changedTouches = touchListFromTouchEventArray([aCoder decodeObjectForKey:CPEventChangedTouchesKey]); | |
if (type in mouseTypes) | |
{ | |
nativeEvent = recorderWindow.document.createEvent("MouseEvent"); | |
nativeEvent.initMouseEvent(type, bubbles, cancelable, recorderWindow, | |
"", screenX, screenY, clientX, clientY, | |
ctrlKey, altKey, shiftKey, metaKey, | |
button, relatedTarget); | |
// nativeEvent.target = target; // ? | |
} | |
else if (type in touchTypes) | |
{ | |
nativeEvent = recorderWindow.document.createEvent("TouchEvent"); | |
nativeEvent.initTouchEvent(type, canBubble, cancelable, recorderWindow, "", screenX, screenY, | |
clientX, clientY, ctrlKey, altKey, shiftKey, metaKey, | |
touches, targetTouches, changedTouches, scale, rotation); | |
} | |
else if (type in keyTypes) | |
{ | |
nativeEvent = recorderWindow.document.createEvent("KeyboardEvent"); | |
nativeEvent.initKeyEvent(type, bubbles, cancelable, recorderWindow, | |
ctrlKey, altKey, shiftKey, metaKey, | |
keyCode, charCode); | |
// nativeEvent.target = target; // ? | |
} | |
else | |
{ | |
nativeEvent = recorderWindow.document.createEvent("Event"); | |
nativeEvent.initEvent(type, bubbles, cancelable); | |
nativeEvent.target = target; // ? | |
nativeEvent.clientX = clientX; | |
nativeEvent.clientY = clientY; | |
nativeEvent.pageX = pageX; | |
nativeEvent.pageY = pageY; | |
nativeEvent.screenX = screenX; | |
nativeEvent.screenY = screenY; | |
nativeEvent.shiftKey = shiftKey; | |
nativeEvent.ctrlKey = ctrlKey; | |
nativeEvent.altKey = altKey; | |
nativeEvent.metaKey = metaKey; | |
} | |
nativeEvent.isa = [CPEvent class]; | |
return nativeEvent; | |
} | |
- (void)encodeWithCoder:(CPCoder)aCoder | |
{ | |
[aCoder encodeBool:self.altKey forKey:CPEventAltKeyKey]; | |
[aCoder encodeBool:self.bubbles forKey:CPEventBubblesKey]; | |
[aCoder encodeInt:self.button forKey:CPEventButtonKey]; | |
[aCoder encodeBool:self.cancelBubble forKey:CPEventCancelBubbleKey]; | |
[aCoder encodeBool:self.cancelable forKey:CPEventCancelableKey]; | |
[aCoder encodeObject:self.charCode forKey:CPEventCharCodeKey]; | |
[aCoder encodeObject:self.clientX forKey:CPEventClientXKey]; | |
[aCoder encodeObject:self.clientY forKey:CPEventClientYKey]; | |
[aCoder encodeBool:self.ctrlKey forKey:CPEventCtrlKeyKey]; | |
if (self.currentTarget) | |
[aCoder encodeObject:getXPathForElement(self.currentTarget, recorderWindow.document) forKey:CPEventCurrentTargetKey]; | |
[aCoder encodeObject:self.eventPhase forKey:CPEventEventPhaseKey]; | |
if (self.explicitOriginalTarget) | |
[aCoder encodeObject:getXPathForElement(self.explicitOriginalTarget, recorderWindow.document) forKey:CPEventExplicitOriginalTargeyKey]; | |
[aCoder encodeBool:self.isChar forKey:CPEventIsCharKey]; | |
[aCoder encodeObject:self.keyCode forKey:CPEventKeyCodeKey]; | |
[aCoder encodeBool:self.metaKey forKey:CPEventMetaKeyKey]; | |
if (self.originalTarget) | |
[aCoder encodeObject:getXPathForElement(self.originalTarget, recorderWindow.document) forKey:CPEventOriginalTargetKey]; | |
[aCoder encodeObject:self.pageX forKey:CPEventPageXKey]; | |
[aCoder encodeObject:self.pageY forKey:CPEventPageYKey]; | |
if (self.relatedTarget) | |
[aCoder encodeObject:getXPathForElement(self.relatedTarget, recorderWindow.document) forKey:CPEventRelatedTargetKey]; | |
[aCoder encodeObject:self.screenX forKey:CPEventScreenXKey]; | |
[aCoder encodeObject:self.screenY forKey:CPEventScreenYKey]; | |
[aCoder encodeBool:self.shiftKey forKey:CPEventShiftKey]; | |
if (self.target) | |
[aCoder encodeObject:getXPathForElement(self.target, recorderWindow.document) forKey:CPEventTargetKey]; | |
[aCoder encodeObject:self.timeStamp forKey:CPEventTimeStampKey]; | |
[aCoder encodeObject:self.type forKey:CPEventTypeKey]; | |
[aCoder encodeObject:self.which forKey:CPEventWhichKey]; | |
if (self.touches) | |
[aCoder encodeObject:touchEventArrayFromTouchList(self.touches) forKey:CPEventTouchesKey]; | |
if (self.targetTouches) | |
[aCoder encodeObject:touchEventArrayFromTouchList(self.targetTouches) forKey:CPEventTargetTouchesKey]; | |
if (self.changedTouches) | |
[aCoder encodeObject:touchEventArrayFromTouchList(self.changedTouches) forKey:CPEventChangedTouchesKey]; | |
[aCoder encodeObject:self.scale forKey:CPEventScaleKey]; | |
[aCoder encodeObject:self.rotation forKey:CPEventRotationKey]; | |
} | |
@end | |
function touchEventArrayFromTouchList(touchList) | |
{ | |
var array = [], | |
count = touchList.length; | |
for (var i = 0; i < count; i++) | |
{ | |
var item = touchList.item(i); | |
array.push({ | |
clientX : item.clientX, | |
clientY : item.clientY, | |
identifier : item.identifier, | |
pageX : item.pageX, | |
pageY : item.pageY, | |
screenX : item.screenX, | |
screenY : item.screenY, | |
target : getXPathForElement(item.target, recorderWindow.document) | |
}); | |
} | |
return array; | |
} | |
function touchListFromTouchEventArray(touchEventArray) | |
{ | |
var count = touchEventArray.length; | |
for (var i = 0; i < count; i++) | |
{ | |
var item = touchEventArray[i]; | |
item.target = getElementFromXPath(item.target); | |
} | |
touchEventArray.item = function(i) | |
{ | |
return touchEventArray[i]; | |
} | |
return touchEventArray; | |
} | |
function getXPathForElement(el, xml) | |
{ | |
var xpath = ''; | |
var pos, tempitem2; | |
while(el !== xml.documentElement) { | |
pos = 0; | |
tempitem2 = el; | |
while(tempitem2) { | |
if (tempitem2.nodeType === 1 && tempitem2.nodeName === el.nodeName) { // If it is ELEMENT_NODE of the same name | |
pos += 1; | |
} | |
tempitem2 = tempitem2.previousSibling; | |
} | |
xpath = "*[name()='"+el.nodeName+"' and namespace-uri()='"+(el.namespaceURI===null?'':el.namespaceURI)+"']["+pos+']'+'/'+xpath; | |
el = el.parentNode; | |
} | |
xpath = '/*'+"[name()='"+xml.documentElement.nodeName+"' and namespace-uri()='"+(el.namespaceURI===null?'':el.namespaceURI)+"']"+'/'+xpath; | |
xpath = xpath.replace(/\/$/, ''); | |
return xpath; | |
} | |
function getElementFromXPath(aExpr, aNode) | |
{ | |
var xpe = new XPathEvaluator(); | |
var nsResolver = xpe.createNSResolver(aNode.ownerDocument == null ? | |
aNode.documentElement : aNode.ownerDocument.documentElement); | |
var result = xpe.evaluate(aExpr, aNode, nsResolver, 0, null), | |
found = [], | |
res; | |
while (res = result.iterateNext()) | |
found.push(res); | |
return found.length === 1 ? found[0] : found; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment