1// Simple Set Clipboard System 2// Author: Joseph Huckaby 3// http://bowser.effectgames.com/~jhuckaby/zeroclipboard/ 4// http://davidwalsh.name/dw-content/zero-clipboard.php 5 6var ZeroClipboard = { 7 8 version: "1.0.7", 9 clients: {}, // registered upload clients on page, indexed by id 10 moviePath: 'ZeroClipboard.swf', // URL to movie 11 nextId: 1, // ID of next movie 12 13 $: function(thingy) { 14 // simple DOM lookup utility function 15 if (typeof(thingy) == 'string') thingy = document.getElementById(thingy); 16 if (!thingy.addClass) { 17 // extend element with a few useful methods 18 thingy.hide = function() { this.style.display = 'none'; }; 19 thingy.show = function() { this.style.display = ''; }; 20 thingy.addClass = function(name) { this.removeClass(name); this.className += ' ' + name; }; 21 thingy.removeClass = function(name) { 22 var classes = this.className.split(/\s+/); 23 var idx = -1; 24 for (var k = 0; k < classes.length; k++) { 25 if (classes[k] == name) { idx = k; k = classes.length; } 26 } 27 if (idx > -1) { 28 classes.splice( idx, 1 ); 29 this.className = classes.join(' '); 30 } 31 return this; 32 }; 33 thingy.hasClass = function(name) { 34 return !!this.className.match( new RegExp("\\s*" + name + "\\s*") ); 35 }; 36 } 37 return thingy; 38 }, 39 40 setMoviePath: function(path) { 41 // set path to ZeroClipboard.swf 42 this.moviePath = path; 43 }, 44 45 dispatch: function(id, eventName, args) { 46 // receive event from flash movie, send to client 47 var client = this.clients[id]; 48 if (client) { 49 client.receiveEvent(eventName, args); 50 } 51 }, 52 53 register: function(id, client) { 54 // register new client to receive events 55 this.clients[id] = client; 56 }, 57 58 getDOMObjectPosition: function(obj, stopObj) { 59 // get absolute coordinates for dom element 60 var info = { 61 left: 0, 62 top: 0, 63 width: obj.width ? obj.width : obj.offsetWidth, 64 height: obj.height ? obj.height : obj.offsetHeight 65 }; 66 67 while (obj && (obj != stopObj)) { 68 info.left += obj.offsetLeft; 69 info.top += obj.offsetTop; 70 obj = obj.offsetParent; 71 } 72 73 return info; 74 }, 75 76 Client: function(elem) { 77 // constructor for new simple upload client 78 this.handlers = {}; 79 80 // unique ID 81 this.id = ZeroClipboard.nextId++; 82 this.movieId = 'ZeroClipboardMovie_' + this.id; 83 84 // register client with singleton to receive flash events 85 ZeroClipboard.register(this.id, this); 86 87 // create movie 88 if (elem) this.glue(elem); 89 } 90}; 91 92ZeroClipboard.Client.prototype = { 93 94 id: 0, // unique ID for us 95 ready: false, // whether movie is ready to receive events or not 96 movie: null, // reference to movie object 97 clipText: '', // text to copy to clipboard 98 handCursorEnabled: true, // whether to show hand cursor, or default pointer cursor 99 cssEffects: true, // enable CSS mouse effects on dom container 100 handlers: null, // user event handlers 101 102 glue: function(elem, appendElem, stylesToAdd) { 103 // glue to DOM element 104 // elem can be ID or actual DOM element object 105 this.domElement = ZeroClipboard.$(elem); 106 107 // float just above object, or zIndex 99 if dom element isn't set 108 var zIndex = 99; 109 if (this.domElement.style.zIndex) { 110 zIndex = parseInt(this.domElement.style.zIndex, 10) + 1; 111 } 112 113 if (typeof(appendElem) == 'string') { 114 appendElem = ZeroClipboard.$(appendElem); 115 } 116 else if (typeof(appendElem) == 'undefined') { 117 appendElem = document.getElementsByTagName('body')[0]; 118 } 119 120 // find X/Y position of domElement 121 var box = ZeroClipboard.getDOMObjectPosition(this.domElement, appendElem); 122 123 // create floating DIV above element 124 this.div = document.createElement('div'); 125 var style = this.div.style; 126 style.position = 'absolute'; 127 style.left = '' + box.left + 'px'; 128 style.top = '' + box.top + 'px'; 129 style.width = '' + box.width + 'px'; 130 style.height = '' + box.height + 'px'; 131 style.zIndex = zIndex; 132 133 if (typeof(stylesToAdd) == 'object') { 134 for (addedStyle in stylesToAdd) { 135 style[addedStyle] = stylesToAdd[addedStyle]; 136 } 137 } 138 139 // style.backgroundColor = '#f00'; // debug 140 141 appendElem.appendChild(this.div); 142 143 this.div.innerHTML = this.getHTML( box.width, box.height ); 144 }, 145 146 getHTML: function(width, height) { 147 // return HTML for movie 148 var html = ''; 149 var flashvars = 'id=' + this.id + 150 '&width=' + width + 151 '&height=' + height; 152 153 if (navigator.userAgent.match(/MSIE/)) { 154 // IE gets an OBJECT tag 155 var protocol = location.href.match(/^https/i) ? 'https://' : 'http://'; 156 html += '<object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="'+protocol+'download.macromedia.com/pub/s
156hockwave/cabs/flash/swflash.cab#version=9,0,0,0" width="'+width+'" height="'+height+'" id="'+this.movieId+'" align="middle"><param name="allowScriptAccess" value="always" /><param name="allowFullScreen" value="false" /><param name="movie" value="'+ZeroClipboard.moviePath+'" /><param name="loop" value="false" /><param name="menu" value="false" /><param name="quality" value="best" /><param name="bgcolor" value="#ffffff" /><param name="flashvars" value="'+flashvars+'"/><param name="wmode" value="transparent"/></object>'; 157 } 158 else { 159 // all other browsers get an EMBED tag 160 html += '<embed id="'+this.movieId+'" src="'+ZeroClipboard.moviePath+'" loop="false" menu="false" quality="best" bgcolor="#ffffff" width="'+width+'" height="'+height+'" name="'+this.movieId+'" align="middle" allowScriptAccess="always" allowFullScreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="'+flashvars+'" wmode="transparent" />'; 161 } 162 return html; 163 }, 164 165 hide: function() { 166 // temporarily hide floater offscreen 167 if (this.div) { 168 this.div.style.left = '-2000px'; 169 } 170 }, 171 172 show: function() { 173 // show ourselves after a call to hide() 174 this.reposition(); 175 }, 176 177 destroy: function() { 178 // destroy control and floater 179 if (this.domElement && this.div) { 180 this.hide(); 181 this.div.innerHTML = ''; 182 183 var body = document.getElementsByTagName('body')[0]; 184 try { body.removeChild( this.div ); } catch(e) {;} 185 186 this.domElement = null; 187 this.div = null; 188 } 189 }, 190 191 reposition: function(elem) { 192 // reposition our floating div, optionally to new container 193 // warning: container CANNOT change size, only position 194 if (elem) { 195 this.domElement = ZeroClipboard.$(elem); 196 if (!this.domElement) this.hide(); 197 } 198 199 if (this.domElement && this.div) { 200 var box = ZeroClipboard.getDOMObjectPosition(this.domElement); 201 var style = this.div.style; 202 style.left = '' + box.left + 'px'; 203 style.top = '' + box.top + 'px'; 204 } 205 }, 206 207 setText: function(newText) { 208 // set text to be copied to clipboard 209 this.clipText = newText; 210 if (this.ready) this.movie.setText(newText); 211 }, 212 213 addEventListener: function(eventName, func) { 214 // add user event listener for event 215 // event types: load, queueStart, fileStart, fileComplete, queueComplete, progress, error, cancel 216 eventName = eventName.toString().toLowerCase().replace(/^on/, ''); 217 if (!this.handlers[eventName]) this.handlers[eventName] = []; 218 this.handlers[eventName].push(func); 219 }, 220 221 setHandCursor: function(enabled) { 222 // enable hand cursor (true), or default arrow cursor (false) 223 this.handCursorEnabled = enabled; 224 if (this.ready) this.movie.setHandCursor(enabled); 225 }, 226 227 setCSSEffects: function(enabled) { 228 // enable or disable CSS effects on DOM container 229 this.cssEffects = !!enabled; 230 }, 231 232 receiveEvent: function(eventName, args) { 233 // receive event from flash 234 eventName = eventName.toString().toLowerCase().replace(/^on/, ''); 235 236 // special behavior for certain events 237 switch (eventName) { 238 case 'load': 239 // movie claims it is ready, but in IE this isn't always the case... 240 // bug fix: Cannot extend EMBED DOM elements in Firefox, must use traditional function 241 this.movie = document.getElementById(this.movieId); 242 if (!this.movie) { 243 var self = this; 244 setTimeout( function() { self.receiveEvent('load', null); }, 1 ); 245 return; 246 } 247 248 // firefox on pc needs a "kick" in order to set these in certain cases 249 if (!this.ready && navigator.userAgent.match(/Firefox/) && navigator.userAgent.match(/Windows/)) { 250 var self = this; 251 setTimeout( function() { self.receiveEvent('load', null); }, 100 ); 252 this.ready = true; 253 return; 254 } 255 256 this.ready = true; 257 this.movie.setText( this.clipText ); 258 this.movie.setHandCursor( this.handCursorEnabled ); 259 break; 260 261 case 'mouseover': 262 if (this.domElement && this.cssEffects) { 263 this.domElement.addClass('hover'); 264 if (this.recoverActive) this.domElement.addClass('active'); 265 } 266 break; 267 268 case 'mouseout': 269 if (this.domElement && this.cssEffects) { 270 this.recoverActive = false;
271 if (this.domElement.hasClass('active')) { 272 this.domElement.removeClass('active'); 273 this.recoverActive = true; 274 } 275 this.domElement.removeClass('hover'); 276 } 277 break; 278 279 case 'mousedown': 280 if (this.domElement && this.cssEffects) { 281 this.domElement.addClass('active'); 282 } 283 break; 284 285 case 'mouseup': 286 if (this.domElement && this.cssEffects) { 287 this.domElement.removeClass('active'); 288 this.recoverActive = false; 289 } 290 break; 291 } // switch eventName 292 293 if (this.handlers[eventName]) { 294 for (var idx = 0, len = this.handlers[eventName].length; idx < len; idx++) { 295 var func = this.handlers[eventName][idx]; 296 297 if (typeof(func) == 'function') { 298 // actual function reference 299 func(this, args); 300 } 301 else if ((typeof(func) == 'object') && (func.length == 2)) { 302 // PHP style object + method, i.e. [myObject, 'myMethod'] 303 func[0][ func[1] ](this, args); 304 } 305 else if (typeof(func) == 'string') { 306 // name of function 307 window[func](this, args); 308 } 309 } // foreach event handler defined 310 } // user defined handler for event 311 } 312 313}; 314
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.