Wed, 31 Dec 2014 06:55:46 +0100
Added tag TORBROWSER_REPLICA for changeset 6474c204b198
michael@0 | 1 | /* |
michael@0 | 2 | * Helper structures to track callbacks from image and channel loads. |
michael@0 | 3 | */ |
michael@0 | 4 | |
michael@0 | 5 | // START_REQUEST and STOP_REQUEST are used by ChannelListener, and |
michael@0 | 6 | // stored in ChannelListener.requestStatus. |
michael@0 | 7 | const START_REQUEST = 0x01; |
michael@0 | 8 | const STOP_REQUEST = 0x02; |
michael@0 | 9 | const DATA_AVAILABLE = 0x04; |
michael@0 | 10 | |
michael@0 | 11 | // One bit per callback that imageListener below implements. Stored in |
michael@0 | 12 | // ImageListener.state. |
michael@0 | 13 | const SIZE_AVAILABLE = 0x01; |
michael@0 | 14 | const FRAME_UPDATE = 0x02; |
michael@0 | 15 | const FRAME_COMPLETE = 0x04; |
michael@0 | 16 | const LOAD_COMPLETE = 0x08; |
michael@0 | 17 | const DECODE_COMPLETE = 0x10; |
michael@0 | 18 | |
michael@0 | 19 | // An implementation of imgIScriptedNotificationObserver with the ability to |
michael@0 | 20 | // call specified functions on onStartRequest and onStopRequest. |
michael@0 | 21 | function ImageListener(start_callback, stop_callback) |
michael@0 | 22 | { |
michael@0 | 23 | this.sizeAvailable = function onSizeAvailable(aRequest) |
michael@0 | 24 | { |
michael@0 | 25 | do_check_false(this.synchronous); |
michael@0 | 26 | |
michael@0 | 27 | this.state |= SIZE_AVAILABLE; |
michael@0 | 28 | |
michael@0 | 29 | if (this.start_callback) |
michael@0 | 30 | this.start_callback(this, aRequest); |
michael@0 | 31 | } |
michael@0 | 32 | this.frameComplete = function onFrameComplete(aRequest) |
michael@0 | 33 | { |
michael@0 | 34 | do_check_false(this.synchronous); |
michael@0 | 35 | |
michael@0 | 36 | this.state |= FRAME_COMPLETE; |
michael@0 | 37 | } |
michael@0 | 38 | this.decodeComplete = function onDecodeComplete(aRequest) |
michael@0 | 39 | { |
michael@0 | 40 | do_check_false(this.synchronous); |
michael@0 | 41 | |
michael@0 | 42 | this.state |= DECODE_COMPLETE; |
michael@0 | 43 | } |
michael@0 | 44 | this.loadComplete = function onLoadcomplete(aRequest) |
michael@0 | 45 | { |
michael@0 | 46 | do_check_false(this.synchronous); |
michael@0 | 47 | |
michael@0 | 48 | try { |
michael@0 | 49 | aRequest.requestDecode(); |
michael@0 | 50 | } catch (e) { |
michael@0 | 51 | do_print("requestDecode threw " + e); |
michael@0 | 52 | } |
michael@0 | 53 | |
michael@0 | 54 | this.state |= LOAD_COMPLETE; |
michael@0 | 55 | |
michael@0 | 56 | if (this.stop_callback) |
michael@0 | 57 | this.stop_callback(this, aRequest); |
michael@0 | 58 | } |
michael@0 | 59 | this.frameUpdate = function onFrameUpdate(aRequest) |
michael@0 | 60 | { |
michael@0 | 61 | } |
michael@0 | 62 | this.isAnimated = function onIsAnimated() |
michael@0 | 63 | { |
michael@0 | 64 | } |
michael@0 | 65 | |
michael@0 | 66 | // Initialize the synchronous flag to true to start. This must be set to |
michael@0 | 67 | // false before exiting to the event loop! |
michael@0 | 68 | this.synchronous = true; |
michael@0 | 69 | |
michael@0 | 70 | // A function to call when onStartRequest is called. |
michael@0 | 71 | this.start_callback = start_callback; |
michael@0 | 72 | |
michael@0 | 73 | // A function to call when onStopRequest is called. |
michael@0 | 74 | this.stop_callback = stop_callback; |
michael@0 | 75 | |
michael@0 | 76 | // The image load/decode state. |
michael@0 | 77 | // A bitfield that tracks which callbacks have been called. Takes the bits |
michael@0 | 78 | // defined above. |
michael@0 | 79 | this.state = 0; |
michael@0 | 80 | } |
michael@0 | 81 | |
michael@0 | 82 | function NS_FAILED(val) |
michael@0 | 83 | { |
michael@0 | 84 | return !!(val & 0x80000000); |
michael@0 | 85 | } |
michael@0 | 86 | |
michael@0 | 87 | function ChannelListener() |
michael@0 | 88 | { |
michael@0 | 89 | this.onStartRequest = function onStartRequest(aRequest, aContext) |
michael@0 | 90 | { |
michael@0 | 91 | if (this.outputListener) |
michael@0 | 92 | this.outputListener.onStartRequest(aRequest, aContext); |
michael@0 | 93 | |
michael@0 | 94 | this.requestStatus |= START_REQUEST; |
michael@0 | 95 | } |
michael@0 | 96 | |
michael@0 | 97 | this.onDataAvailable = function onDataAvailable(aRequest, aContext, aInputStream, aOffset, aCount) |
michael@0 | 98 | { |
michael@0 | 99 | if (this.outputListener) |
michael@0 | 100 | this.outputListener.onDataAvailable(aRequest, aContext, aInputStream, aOffset, aCount); |
michael@0 | 101 | |
michael@0 | 102 | this.requestStatus |= DATA_AVAILABLE; |
michael@0 | 103 | } |
michael@0 | 104 | |
michael@0 | 105 | this.onStopRequest = function onStopRequest(aRequest, aContext, aStatusCode) |
michael@0 | 106 | { |
michael@0 | 107 | if (this.outputListener) |
michael@0 | 108 | this.outputListener.onStopRequest(aRequest, aContext, aStatusCode); |
michael@0 | 109 | |
michael@0 | 110 | // If we failed (or were canceled - failure is implied if canceled), |
michael@0 | 111 | // there's no use tracking our state, since it's meaningless. |
michael@0 | 112 | if (NS_FAILED(aStatusCode)) |
michael@0 | 113 | this.requestStatus = 0; |
michael@0 | 114 | else |
michael@0 | 115 | this.requestStatus |= STOP_REQUEST; |
michael@0 | 116 | } |
michael@0 | 117 | |
michael@0 | 118 | // A listener to pass the notifications we get to. |
michael@0 | 119 | this.outputListener = null; |
michael@0 | 120 | |
michael@0 | 121 | // The request's status. A bitfield that holds one or both of START_REQUEST |
michael@0 | 122 | // and STOP_REQUEST, according to which callbacks have been called on the |
michael@0 | 123 | // associated request. |
michael@0 | 124 | this.requestStatus = 0; |
michael@0 | 125 | } |