├── ChromeExtension ├── event_emitter.min.js ├── fbGraffiti.js ├── images │ ├── howTo.png │ ├── notifIcon.png │ ├── share.png │ ├── spray.png │ ├── sprayCan.png │ ├── sprayIcon copy.png │ ├── sprayIcon.png │ ├── sprayIconWhite.png │ └── throwingMice.png ├── jquery.min.js ├── manifest.json ├── popup.html ├── popup.js ├── spectrum.js └── src.js ├── ChromeExtensionDev ├── event_emitter.min.js ├── fbGraffiti.js ├── images │ ├── notifIcon.png │ ├── share.png │ ├── spray.png │ ├── sprayCan.png │ ├── sprayIcon copy.png │ ├── sprayIcon.png │ ├── sprayIconWhite.png │ └── throwingMice.png ├── jquery.min.js ├── manifest.json ├── popup.html ├── popup.js └── spectrum.js ├── LICENSE.md ├── README.md └── server ├── adapters ├── db.coffee └── s3.coffee ├── bundle.coffee ├── client ├── button.css ├── jquery-1.7.1.min.js ├── jquery.masonry.min.js └── style.css ├── init.coffee ├── package.json ├── public ├── DomCoolTest.coffee ├── DrawTools.coffee ├── FbgCanvas.coffee ├── FbgImg.coffee ├── ImageCache.coffee ├── index.coffee ├── main.coffee ├── mouseAdapter.coffee ├── notif.coffee ├── spectrum.css.coffee └── trending.coffee ├── requestHandlers ├── auth.coffee ├── browse.coffee ├── clear.coffee ├── count.coffee ├── ignoreReport.coffee ├── index.coffee ├── notifCount.coffee ├── optOut.coffee ├── report.coffee ├── setImage.coffee ├── shareImage.coffee ├── shareSrc.coffee ├── stats.coffee └── topPages.coffee ├── server.coffee ├── uploadPublic.coffee └── views ├── adminLogin.jade ├── browse.jade ├── browseReported.jade ├── share.jade └── topPages.jade /ChromeExtension/event_emitter.min.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * EventEmitter v4.2.11 - git.io/ee 3 | * Unlicense - http://unlicense.org/ 4 | * Oliver Caldwell - http://oli.me.uk/ 5 | * @preserve 6 | */ 7 | (function(){"use strict";function t(){}function i(t,n){for(var e=t.length;e--;)if(t[e].listener===n)return e;return-1}function n(e){return function(){return this[e].apply(this,arguments)}}var e=t.prototype,r=this,s=r.EventEmitter;e.getListeners=function(n){var r,e,t=this._getEvents();if(n instanceof RegExp){r={};for(e in t)t.hasOwnProperty(e)&&n.test(e)&&(r[e]=t[e])}else r=t[n]||(t[n]=[]);return r},e.flattenListeners=function(t){var e,n=[];for(e=0;e UPDATE_INTERVAL) { 35 | console.log('Updating from server.'); 36 | window.updateFBG(); 37 | } 38 | if (items.FBG_Active) { 39 | if (items.code) { 40 | execute(items.code); 41 | } else { 42 | get(source, execute); 43 | } 44 | } 45 | }); -------------------------------------------------------------------------------- /ChromeExtension/images/howTo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joel-simon/FB-Graffiti/d6b4502afbd34a020919686943d211084f1bdb65/ChromeExtension/images/howTo.png -------------------------------------------------------------------------------- /ChromeExtension/images/notifIcon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joel-simon/FB-Graffiti/d6b4502afbd34a020919686943d211084f1bdb65/ChromeExtension/images/notifIcon.png -------------------------------------------------------------------------------- /ChromeExtension/images/share.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joel-simon/FB-Graffiti/d6b4502afbd34a020919686943d211084f1bdb65/ChromeExtension/images/share.png -------------------------------------------------------------------------------- /ChromeExtension/images/spray.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joel-simon/FB-Graffiti/d6b4502afbd34a020919686943d211084f1bdb65/ChromeExtension/images/spray.png -------------------------------------------------------------------------------- /ChromeExtension/images/sprayCan.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joel-simon/FB-Graffiti/d6b4502afbd34a020919686943d211084f1bdb65/ChromeExtension/images/sprayCan.png -------------------------------------------------------------------------------- /ChromeExtension/images/sprayIcon copy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joel-simon/FB-Graffiti/d6b4502afbd34a020919686943d211084f1bdb65/ChromeExtension/images/sprayIcon copy.png -------------------------------------------------------------------------------- /ChromeExtension/images/sprayIcon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joel-simon/FB-Graffiti/d6b4502afbd34a020919686943d211084f1bdb65/ChromeExtension/images/sprayIcon.png -------------------------------------------------------------------------------- /ChromeExtension/images/sprayIconWhite.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joel-simon/FB-Graffiti/d6b4502afbd34a020919686943d211084f1bdb65/ChromeExtension/images/sprayIconWhite.png -------------------------------------------------------------------------------- /ChromeExtension/images/throwingMice.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joel-simon/FB-Graffiti/d6b4502afbd34a020919686943d211084f1bdb65/ChromeExtension/images/throwingMice.png -------------------------------------------------------------------------------- /ChromeExtension/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "manifest_version": 2, 3 | 4 | "name": "FB Graffiti", 5 | "description": "Facebook walls are now open to graffiti.", 6 | "version": "2.1.1", 7 | 8 | "permissions": [ 9 | "tabs", "https://www.facebook.com/*" ,"storage" 10 | ], 11 | "web_accessible_resources": [ 12 | "images/sprayCan.png", 13 | "images/share.png", 14 | "images/howTo.png", 15 | "jquery.min.js", 16 | "spectrum.js", 17 | "event_emitter.min.js", 18 | "fbGraffiti.js" 19 | ], 20 | "browser_action": { 21 | "default_icon": "images/spray.png", 22 | "default_popup": "popup.html" 23 | }, 24 | "content_scripts": [{ 25 | "js" : ["jquery.min.js", "spectrum.js", "event_emitter.min.js","src.js"], 26 | "matches": ["https://www.facebook.com/*"] 27 | }] 28 | } -------------------------------------------------------------------------------- /ChromeExtension/popup.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Graffiti 6 | 20 | 21 | 22 | 23 | 24 | 25 |

Click on any FB image and draw

26 |

27 | 28 | FAQ
29 | Open Source
30 | Feedback 31 | 32 | 33 | -------------------------------------------------------------------------------- /ChromeExtension/popup.js: -------------------------------------------------------------------------------- 1 | document.addEventListener('DOMContentLoaded', function () { 2 | var divs = document.querySelectorAll('a'); 3 | for (var i = 0; i < divs.length; i++) { 4 | divs[i].addEventListener('click', function() { 5 | chrome.tabs.create({url: this.href}); 6 | return false; 7 | }); 8 | } 9 | var imgURL = chrome.extension.getURL("images/howTo.png"); 10 | var img = document.createElement("IMG"); 11 | img.src = imgURL; 12 | img.style.width = '100%'; 13 | document.getElementById("photo").appendChild(img); 14 | chrome.storage.local.get({ 15 | FBG_Active: true, 16 | }, function(items) { 17 | addButton(items.FBG_Active) 18 | }); 19 | }); 20 | 21 | function addButton (active) { 22 | button = document.getElementById("toggle"); 23 | button.style.float = 'right'; 24 | 25 | updateText(button, active); 26 | button.addEventListener("click", function () { 27 | active = !active; 28 | updateText(button, active); 29 | chrome.storage.local.set({ FBG_Active: active }) 30 | }); 31 | } 32 | 33 | function updateText (button, active) { 34 | console.log(button); 35 | if (active) button.innerHTML = 'Turn Off FB Graffiti'; 36 | else button.innerHTML = 'Turn On FB Graffiti'; 37 | } -------------------------------------------------------------------------------- /ChromeExtension/src.js: -------------------------------------------------------------------------------- 1 | (function() { 2 | var DomCoolTest, 3 | __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }; 4 | 5 | DomCoolTest = (function() { 6 | function DomCoolTest(onCool, t) { 7 | this.onCool = onCool; 8 | this.t = t; 9 | this.warm = __bind(this.warm, this); 10 | this.timer = null; 11 | } 12 | 13 | DomCoolTest.prototype.warm = function() { 14 | if (this.timer != null) { 15 | clearTimeout(this.timer); 16 | this.timer = null; 17 | } 18 | return this.timer = setTimeout(((function(_this) { 19 | return function() { 20 | _this.timer = null; 21 | return _this.onCool(); 22 | }; 23 | })(this)), this.t); 24 | }; 25 | 26 | DomCoolTest.prototype.isWarm = function() { 27 | return this.timer != null; 28 | }; 29 | 30 | return DomCoolTest; 31 | 32 | })(); 33 | 34 | if (window.fbg == null) { 35 | window.fbg = {}; 36 | } 37 | 38 | window.fbg.DomCoolTest = DomCoolTest; 39 | 40 | }).call(this); 41 | (function() { 42 | fbg.DrawTools = (function() { 43 | function DrawTools() { 44 | var colorPicker, donate, downloadButton, drawButton, dropper, items, rangePicker, reportButton, selectors, showGraffitiButton, text, tip, utilities; 45 | this.selectorOpen = false; 46 | this.eyeDropping = false; 47 | this.container = $('
').css({ 48 | height: 50, 49 | margin: 4, 50 | position: 'absolute', 51 | cursor: 'pointer' 52 | }); 53 | selectors = $('
').css('float', 'left'); 54 | utilities = $('
').css('float', 'left'); 55 | selectors.hide(); 56 | rangePicker = $('').css({ 57 | width: 60, 58 | float: 'left' 59 | }).click(function(e) { 60 | return e.stopPropagation(); 61 | }).change((function(_this) { 62 | return function() { 63 | return _this.updateCursor(); 64 | }; 65 | })(this)); 66 | dropper = $('').attr({ 67 | id: 'dropper', 68 | src: 'http://simpleicon.com/wp-content/uploads/eyedropper-64x64.png' 69 | }).css({ 70 | float: 'left' 71 | }).click((function(_this) { 72 | return function() { 73 | var color; 74 | color = _this.eyeDropping ? 'white' : 'black'; 75 | dropper.css('border-color', color); 76 | _this.eyeDropping = !_this.eyeDropping; 77 | return _this.updateCursor(); 78 | }; 79 | })(this)); 80 | colorPicker = $("").attr({ 81 | id: 'custom' 82 | }).css({ 83 | float: 'left' 84 | }).prependTo(selectors).spectrum({ 85 | color: "#000", 86 | change: (function(_this) { 87 | return function(c) { 88 | return _this.updateCursor(); 89 | }; 90 | })(this), 91 | show: (function(_this) { 92 | return function() { 93 | return _this.selectorOpen = true; 94 | }; 95 | })(this), 96 | hide: (function(_this) { 97 | return function() { 98 | _this.selectorOpen = false; 99 | return _this.updateCursor(); 100 | }; 101 | })(this) 102 | }); 103 | showGraffitiButton = $('').css({ 104 | float: 'left', 105 | width: 80 106 | }).click(function() { 107 | if (fbg.showGraffiti) { 108 | $(this).text('Show'); 109 | fbg.canvas.hide(); 110 | } else { 111 | $(this).text('Hide graffiti'); 112 | fbg.canvas.show(); 113 | } 114 | return fbg.showGraffiti = !fbg.showGraffiti; 115 | }); 116 | drawButton = $('').text(fbg.drawing ? 'Stop' : 'Draw').css({ 117 | float: 'left', 118 | width: 80 119 | }).click((function(_this) { 120 | return function() { 121 | if (fbg.drawing) { 122 | fbg.get.faceBoxes().show(); 123 | drawButton.text('Draw'); 124 | fbg.canvas.postToServer(); 125 | } else { 126 | fbg.get.faceBoxes().hide(); 127 | drawButton.text('Stop'); 128 | } 129 | selectors.toggle(); 130 | utilities.toggle(); 131 | if (!fbg.showGraffiti && fbg.drawing === false) { 132 | showGraffitiButton.trigger('click'); 133 | } 134 | fbg.drawing = !fbg.drawing; 135 | return _this.updateCursor(); 136 | }; 137 | })(this)); 138 | reportButton = $('').css({ 139 | float: 'left', 140 | width: 80 141 | }).click((function(_this) { 142 | return function() { 143 | var data, report, text; 144 | text = 'Does this graffiti contain any: abuse, harrasment or egregiously offensive material? Remember, you can always remove graffiti from your own photos! For more information visit http://fbgraffiti.com/faq/'; 145 | report = confirm(text); 146 | if (report) { 147 | data = { 148 | id: fbg.canvas.id 149 | }; 150 | $.ajax({ 151 | type: 'POST', 152 | url: "" + fbg.host + "report", 153 | data: data 154 | }); 155 | return alert('It will be evaluated and potentially removed, thanks.'); 156 | } 157 | }; 158 | })(this)); 159 | this.undoButton = $('').css({ 160 | float: 'left', 161 | width: 80 162 | }).click((function(_this) { 163 | return function() { 164 | fbg.canvas.undo(); 165 | if (fbg.canvas.history.length === 0) { 166 | return _this.undoButton.prop("disabled", true); 167 | } 168 | }; 169 | })(this)); 170 | downloadButton = $('Download').css({ 171 | float: 'left', 172 | width: 80, 173 | 'margin-top': 2 174 | }).click(function() { 175 | alert('Tweet with #fbgraffiti or @fb_graffiti!'); 176 | this.href = fbg.canvas["export"](); 177 | return this.download = fbg.canvas.id + '.png'; 178 | }); 179 | tip = $('

').css({ 180 | position: 'absolute' 181 | }); 182 | items = ['Hide graffiti to tag photos', 'Turn the entire extension on/off from the chrome extension button']; 183 | text = 'Tip: ' + items[Math.floor(Math.random() * items.length)]; 184 | tip.text(text); 185 | donate = $('SUPPORT').css({ 186 | position: 'absolute', 187 | top: 25, 188 | left: 140 189 | }); 190 | dropper.prependTo(selectors); 191 | rangePicker.prependTo(selectors); 192 | this.undoButton.appendTo(selectors); 193 | showGraffitiButton.appendTo(utilities); 194 | reportButton.appendTo(utilities); 195 | downloadButton.appendTo(utilities); 196 | drawButton.appendTo(this.container); 197 | selectors.appendTo(this.container); 198 | utilities.appendTo(this.container); 199 | this.container.prependTo($(document.body)); 200 | fbg.mouse.addListener('mousemove', (function(_this) { 201 | return function(_arg) { 202 | var c, currX, currY, onCanvas; 203 | currX = _arg.currX, currY = _arg.currY, onCanvas = _arg.onCanvas; 204 | if (_this.eyeDropping && onCanvas) { 205 | c = fbg.canvas.getColor(currX, currY); 206 | return _this.setColor(c); 207 | } 208 | }; 209 | })(this)); 210 | fbg.mouse.addListener('mousedown', (function(_this) { 211 | return function(_arg) { 212 | var onCanvas; 213 | onCanvas = _arg.onCanvas; 214 | $('#custom').spectrum("hide"); 215 | if (_this.eyeDropping && onCanvas) { 216 | return dropper.trigger('click'); 217 | } 218 | }; 219 | })(this)); 220 | this.hide(); 221 | } 222 | 223 | DrawTools.prototype.hide = function() { 224 | $('#custom').spectrum("hide"); 225 | this.undoButton.prop("disabled", true); 226 | return this.container.hide(); 227 | }; 228 | 229 | DrawTools.prototype.show = function() { 230 | $('.rhcHeader').css('height', 50).prepend(this.container); 231 | $('#toggleG').text('Hide graffiti'); 232 | this.updateCursor(); 233 | return this.container.show(); 234 | }; 235 | 236 | DrawTools.prototype.setColor = function(c) { 237 | return $('#custom').spectrum('set', c); 238 | }; 239 | 240 | DrawTools.prototype.color = function() { 241 | var t; 242 | t = $('#custom').spectrum('get'); 243 | if (t != null) { 244 | return t.toRgbString(); 245 | } else { 246 | return "rgba(255, 0, 0, 0)"; 247 | } 248 | }; 249 | 250 | DrawTools.prototype.size = function() { 251 | var _ref; 252 | return (parseInt((_ref = $('#brushRange')[0]) != null ? _ref.value : void 0) / 3) + 2; 253 | }; 254 | 255 | DrawTools.prototype.updateCursor = function(color) { 256 | var ctx, cursor, size; 257 | if (!fbg.drawing) { 258 | return $('.canvas').css({ 259 | 'cursor': 'default' 260 | }); 261 | } else if (this.eyeDropping) { 262 | return $('.canvas').css({ 263 | 'cursor': 'crosshair' 264 | }); 265 | } else { 266 | cursor = document.createElement('canvas'); 267 | ctx = cursor.getContext('2d'); 268 | color = $('#custom').spectrum('get'); 269 | size = this.size(); 270 | cursor.width = size * 2; 271 | cursor.height = size * 2; 272 | ctx.beginPath(); 273 | ctx.arc(size, size, size, 0, 2 * Math.PI, false); 274 | ctx.fillStyle = color.toRgbString(); 275 | ctx.fill(); 276 | ctx.lineWidth = 1; 277 | ctx.strokeStyle = color.getBrightness() > 100 ? '#000000' : '#FFFFFF'; 278 | ctx.stroke(); 279 | return $('.canvas').css({ 280 | 'cursor': "url(" + (cursor.toDataURL()) + ") " + size + " " + size + ", auto" 281 | }); 282 | } 283 | }; 284 | 285 | return DrawTools; 286 | 287 | })(); 288 | 289 | }).call(this); 290 | (function() { 291 | fbg.FbgCanvas = (function() { 292 | function FbgCanvas(img, id, url) { 293 | var height, left, top, width; 294 | this.img = img; 295 | this.id = id; 296 | this.changesMade = false; 297 | this.img.addClass('hasCanvas'); 298 | this.stage = $('.stage').first(); 299 | this.owner = fbg.get.owner() || fbg.urlParser.owner(fbg.currentPage); 300 | this.history = []; 301 | top = "" + (Math.floor((this.stage.height() - this.img.height()) / 2)) + "px"; 302 | left = "" + (Math.floor((this.stage.width() - this.img.width()) / 2)) + "px"; 303 | width = this.img.width(); 304 | height = this.img.height(); 305 | this.canvas = $('').attr({ 306 | id: "canvas" + this.id, 307 | width: width, 308 | height: height 309 | }).css({ 310 | position: 'absolute', 311 | top: top, 312 | left: left, 313 | cursor: "crosshair", 314 | 'z-index': 2 315 | }).addClass('canvas').click(function(e) { 316 | console.log('getting click'); 317 | return e.stopPropagation(); 318 | }); 319 | this.ctx = this.canvas[0].getContext('2d'); 320 | this.graffitiImage = $('').attr({ 321 | src: url, 322 | id: "" + this.id + "img", 323 | 'crossOrigin': 'anonymous' 324 | }).load((function(_this) { 325 | return function() { 326 | _this.img.addClass('hasGraffiti'); 327 | return _this.ctx.drawImage(_this.graffitiImage[0], 0, 0, width, height); 328 | }; 329 | })(this)); 330 | this.createImgCopy((function(_this) { 331 | return function(_arg) { 332 | var canvas, ctx; 333 | canvas = _arg.canvas, ctx = _arg.ctx; 334 | _this.fbImgCtx = ctx; 335 | return _this.fbImgCanvas = canvas; 336 | }; 337 | })(this)); 338 | } 339 | 340 | FbgCanvas.prototype.saveState = function() { 341 | this.history.push(this.canvas[0].toDataURL()); 342 | return fbg.drawTools.undoButton.prop("disabled", false); 343 | }; 344 | 345 | FbgCanvas.prototype.undo = function() { 346 | var h, img, restore_state, w; 347 | restore_state = this.history.pop(); 348 | if (restore_state == null) { 349 | return; 350 | } 351 | img = new Image; 352 | w = this.canvas[0].width; 353 | h = this.canvas[0].height; 354 | if (this.history.length === 0) { 355 | this.changesMade = false; 356 | } 357 | img.onload = (function(_this) { 358 | return function() { 359 | _this.ctx.clearRect(0, 0, w, h); 360 | return _this.ctx.drawImage(img, 0, 0, w, h); 361 | }; 362 | })(this); 363 | img.src = restore_state; 364 | return null; 365 | }; 366 | 367 | FbgCanvas.prototype.resize = function() { 368 | var height, width; 369 | width = this.img.width(); 370 | height = this.img.height(); 371 | this.canvas.attr({ 372 | width: width, 373 | height: height 374 | }); 375 | if (this.img.hasClass('hasGraffiti')) { 376 | return this.ctx.drawImage(this.graffitiImage[0], 0, 0, width, height); 377 | } 378 | }; 379 | 380 | FbgCanvas.prototype.draw = function(_arg) { 381 | var currX, currY, prevX, prevY, r; 382 | prevX = _arg.prevX, prevY = _arg.prevY, currX = _arg.currX, currY = _arg.currY; 383 | if (fbg.drawTools.selectorOpen) { 384 | return; 385 | } 386 | this.changesMade = true; 387 | r = fbg.drawTools.size(); 388 | this.ctx.beginPath(); 389 | this.ctx.moveTo(prevX, prevY); 390 | this.ctx.lineTo(currX, currY); 391 | this.ctx.strokeStyle = fbg.drawTools.color(); 392 | this.ctx.lineCap = 'round'; 393 | this.ctx.lineWidth = r * 2; 394 | this.ctx.stroke(); 395 | return this.ctx.closePath(); 396 | }; 397 | 398 | FbgCanvas.prototype.addTo = function(div) { 399 | return div.prepend(this.canvas); 400 | }; 401 | 402 | FbgCanvas.prototype.remove = function() { 403 | var img; 404 | this.hide(); 405 | if (this.changesMade) { 406 | img = this.canvas[0].toDataURL(); 407 | this.postToServer(img); 408 | this.addToOtherCopies(img); 409 | } 410 | this.canvas.remove(); 411 | fbg.drawTools.hide(); 412 | this.img.removeClass('hasCanvas'); 413 | return delete fbg.canvas; 414 | }; 415 | 416 | FbgCanvas.prototype.hide = function() { 417 | return this.canvas.hide(); 418 | }; 419 | 420 | FbgCanvas.prototype.show = function() { 421 | return this.canvas.show(); 422 | }; 423 | 424 | FbgCanvas.prototype.postToServer = function(img) { 425 | var data, error; 426 | if (!this.changesMade) { 427 | return; 428 | } 429 | if (img == null) { 430 | img = this.canvas[0].toDataURL(); 431 | } 432 | data = { 433 | id: this.id, 434 | img: img, 435 | url: this.img.attr('src'), 436 | owner: this.owner 437 | }; 438 | error = function(XHR, err) { 439 | return console.log("There was an error posting to server " + err); 440 | }; 441 | return $.ajax({ 442 | type: 'POST', 443 | url: "" + fbg.host + "setImage", 444 | data: data, 445 | error: error 446 | }); 447 | }; 448 | 449 | FbgCanvas.prototype.addToOtherCopies = function(canvasImg) { 450 | var ctx, height, id, newImage, newImageCanvas, width; 451 | width = this.img.width(); 452 | height = this.img.height(); 453 | if (this.img.hasClass('hasGraffiti')) { 454 | newImageCanvas = $('').attr({ 455 | width: width, 456 | height: height 457 | }); 458 | ctx = newImageCanvas[0].getContext('2d'); 459 | ctx.drawImage(this.canvas[0], 0, 0, width, height); 460 | newImage = newImageCanvas[0].toDataURL(); 461 | fbg.cache.add(this.id, newImage); 462 | return $(".img" + this.id).not('.spotlight').each(function() { 463 | var img; 464 | img = $(this); 465 | return img.attr({ 466 | src: newImage 467 | }); 468 | }); 469 | } else { 470 | fbg.cache.add(this.id, canvasImg); 471 | id = this.id; 472 | return $(document.body).find('img').not('.hasGraffiti').not('.spotlight').each(function() { 473 | var img, _id; 474 | img = $(this); 475 | _id = fbg.urlParser.id(this.src); 476 | if (!_id) { 477 | return; 478 | } 479 | if (_id[1] === id) { 480 | return new fbg.FbgImg(img, id, canvasImg); 481 | } 482 | }); 483 | } 484 | }; 485 | 486 | 487 | /* 488 | Export the two canvas layers into one canvas. 489 | */ 490 | 491 | FbgCanvas.prototype["export"] = function() { 492 | var canvas, ctx, h, w, _ref; 493 | canvas = document.createElement('canvas'); 494 | ctx = canvas.getContext("2d"); 495 | _ref = [this.img.width(), this.img.height()], w = _ref[0], h = _ref[1]; 496 | canvas.width = w; 497 | canvas.height = h; 498 | console.log(this.fbImgCanvas[0], this.canvas[0]); 499 | ctx.drawImage(this.fbImgCanvas, 0, 0); 500 | ctx.drawImage(this.canvas[0], 0, 0); 501 | return canvas.toDataURL(); 502 | }; 503 | 504 | FbgCanvas.prototype.createImgCopy = function(callback) { 505 | var copy, src; 506 | src = this.img[0].src; 507 | copy = new Image; 508 | copy.crossOrigin = "Anonymous"; 509 | copy.onload = (function(_this) { 510 | return function() { 511 | var canvas, ctx; 512 | canvas = document.createElement('canvas'); 513 | canvas.width = _this.img.width(); 514 | canvas.height = _this.img.height(); 515 | ctx = canvas.getContext("2d"); 516 | ctx.drawImage(copy, 0, 0, _this.img.width(), _this.img.height()); 517 | return callback({ 518 | canvas: canvas, 519 | ctx: ctx 520 | }); 521 | }; 522 | })(this); 523 | return copy.src = src; 524 | }; 525 | 526 | FbgCanvas.prototype.getColor = function(x, y) { 527 | var a, b, g, r, _ref, _ref1; 528 | _ref = this.ctx.getImageData(x, y, 1, 1).data, r = _ref[0], g = _ref[1], b = _ref[2], a = _ref[3]; 529 | if (a === 255) { 530 | return "rgb(" + r + ", " + g + ", " + b + ")"; 531 | } 532 | _ref1 = this.fbImgCtx.getImageData(x, y, 1, 1).data, r = _ref1[0], g = _ref1[1], b = _ref1[2], a = _ref1[3]; 533 | return "rgb(" + r + ", " + g + ", " + b + ")"; 534 | }; 535 | 536 | return FbgCanvas; 537 | 538 | })(); 539 | 540 | }).call(this); 541 | (function() { 542 | var FbgImg; 543 | 544 | FbgImg = (function() { 545 | function FbgImg(img, key, url) { 546 | var css, domElem; 547 | img.addClass('hasGraffiti'); 548 | css = { 549 | position: 'absolute', 550 | 'z-index': 3 551 | }; 552 | img.parent().css({ 553 | 'overflow': 'hidden' 554 | }); 555 | css.left = img.css('left'); 556 | if (img.css('top') !== '0px') { 557 | css.top = img.css('top'); 558 | } 559 | if (img.css('marginLeft') !== '0px') { 560 | css.marginLeft = img.css('marginLeft'); 561 | } 562 | if (img.css('marginTop') !== '0px') { 563 | css.marginTop = img.css('marginTop'); 564 | } 565 | domElem = $('').addClass('img' + key).css(css).load(function(e) { 566 | img.parent().prepend($(this)); 567 | if (img.hasClass('profilePic')) { 568 | if ($(this).css('height') > $(this).css('width')) { 569 | return $(this).css('width', img.outerWidth()); 570 | } else { 571 | $(this).css('height', img.outerHeight()); 572 | return $(this).css('left', (img.outerWidth() - $(this).width()) / 2); 573 | } 574 | } else { 575 | return $(this).css('width', img.outerWidth()); 576 | } 577 | }).error(function(e) { 578 | img.removeClass('hasGraffiti'); 579 | return fbg.cache.doesntExist(key); 580 | }).attr({ 581 | src: url 582 | }); 583 | } 584 | 585 | return FbgImg; 586 | 587 | })(); 588 | 589 | if (window.fbg == null) { 590 | window.fbg = {}; 591 | } 592 | 593 | window.fbg.FbgImg = FbgImg; 594 | 595 | }).call(this); 596 | (function() { 597 | var ImageCache; 598 | 599 | ImageCache = (function() { 600 | function ImageCache() { 601 | this.forced = {}; 602 | this.local = {}; 603 | } 604 | 605 | ImageCache.prototype["break"] = function(id) { 606 | this.forced[id] = true; 607 | return localStorage.setItem("fbgEmpty:" + id, null); 608 | }; 609 | 610 | ImageCache.prototype.add = function(id, url) { 611 | return this.local[id] = url; 612 | }; 613 | 614 | ImageCache.prototype.doesntExist = function(id) { 615 | return localStorage.setItem("fbgEmpty:" + id, Math.floor(Date.now() / 1000)); 616 | }; 617 | 618 | ImageCache.prototype.past24Hours = function(t) { 619 | return t > (Math.floor(Date.now() / 1000)) - 24 * 60 * 60; 620 | }; 621 | 622 | ImageCache.prototype.idToUrl = function(id) { 623 | var isEmpty, q, s3Url; 624 | s3Url = "https://s3.amazonaws.com/facebookGraffiti/"; 625 | isEmpty = localStorage.getItem("fbgEmpty:" + id); 626 | if (this.local[id] != null) { 627 | return this.local[id]; 628 | } 629 | if ((isEmpty != null) && this.past24Hours(isEmpty)) { 630 | return null; 631 | } 632 | if (this.forced[id]) { 633 | q = "?dummy=" + ((Math.random() + '').substr(2)); 634 | this.forced[id] = false; 635 | } 636 | return "" + s3Url + id + ".png" + (q || ''); 637 | }; 638 | 639 | return ImageCache; 640 | 641 | })(); 642 | 643 | if (window.fbg == null) { 644 | window.fbg = {}; 645 | } 646 | 647 | window.fbg.ImageCache = ImageCache; 648 | 649 | }).call(this); 650 | (function() { 651 | var currX, currY, dragging, onMouse, prevX, prevY; 652 | 653 | prevX = 0; 654 | 655 | currX = 0; 656 | 657 | prevY = 0; 658 | 659 | currY = 0; 660 | 661 | dragging = null; 662 | 663 | document.addEventListener("mousemove", (function(e) { 664 | return onMouse('move', e); 665 | }), false); 666 | 667 | document.addEventListener("mousedown", (function(e) { 668 | return onMouse('down', e); 669 | }), false); 670 | 671 | document.addEventListener("mouseup", (function(e) { 672 | return onMouse('up', e); 673 | }), false); 674 | 675 | document.addEventListener("mouseout", (function(e) { 676 | return onMouse('out', e); 677 | }), false); 678 | 679 | if (window.fbg == null) { 680 | window.fbg = {}; 681 | } 682 | 683 | onMouse = function(eventType, e) { 684 | var onCanvas, options; 685 | if (!fbg.canvas) { 686 | return; 687 | } 688 | onCanvas = e.target === fbg.canvas.canvas[0]; 689 | if (eventType === 'down') { 690 | prevX = currX; 691 | prevY = currY; 692 | currX = e.offsetX; 693 | currY = e.offsetY; 694 | dragging = true; 695 | options = { 696 | currX: currX, 697 | currY: currY, 698 | prevX: prevX, 699 | prevY: prevY, 700 | onCanvas: onCanvas 701 | }; 702 | fbg.mouse.emitEvent('mousedown', [options]); 703 | } 704 | if (dragging && eventType === 'up' || dragging && eventType === "out") { 705 | fbg.mouse.emitEvent('mouseup', [ 706 | { 707 | dragging: dragging 708 | } 709 | ]); 710 | dragging = false; 711 | } 712 | if (eventType === 'move') { 713 | prevX = currX; 714 | prevY = currY; 715 | currX = e.offsetX; 716 | currY = e.offsetY; 717 | options = { 718 | currX: currX, 719 | currY: currY, 720 | prevX: prevX, 721 | prevY: prevY, 722 | onCanvas: onCanvas, 723 | dragging: dragging 724 | }; 725 | return fbg.mouse.emitEvent('mousemove', [options]); 726 | } 727 | }; 728 | 729 | }).call(this); 730 | (function() { 731 | fbg.createNotif = function() { 732 | var countBox, countText, createIframe, data, flyout, haveIframe, id, iframeCss, jewel, jewelButton, jewelSrc, jewelSrcWhite, lastLogin, left, parent, picker, visible, width; 733 | data = {}; 734 | parent = $('#fbRequestsJewel').parent(); 735 | jewelSrc = fbg.imgHost + 'sprayIcon.png'; 736 | jewelSrcWhite = fbg.imgHost + 'sprayIconWhite.png'; 737 | visible = false; 738 | jewelButton = $('
').addClass('_4962'); 739 | jewel = $('', { 740 | src: jewelSrc 741 | }); 742 | jewelButton.append(jewel); 743 | countBox = $('
').css({ 744 | position: 'absolute', 745 | top: -4, 746 | left: 20, 747 | 'background-color': 'red', 748 | height: 20, 749 | 'border-radius': 3, 750 | display: 'none' 751 | }); 752 | countText = $('

3

').css({ 753 | color: 'white', 754 | margin: 4 755 | }); 756 | countBox.append(countText); 757 | jewelButton.append(countBox); 758 | width = 430; 759 | left = -200; 760 | flyout = $('
').attr({}).css({ 761 | 'z-index': 10, 762 | position: 'absolute', 763 | 'margin-top': 3 764 | }).hide(); 765 | picker = $('

Graffiti on your photos.

').css({ 766 | position: 'relative', 767 | left: left, 768 | width: width, 769 | 'background-color': 'white', 770 | 'z-index': 11, 771 | 'border-left-style': 'solid', 772 | 'border-color': 'grey', 773 | 'border-width': 2 774 | }).appendTo(flyout); 775 | iframeCss = { 776 | width: width, 777 | height: 500, 778 | position: 'relative', 779 | left: left, 780 | 'background-color': 'white', 781 | 'border-top-style': 'none' 782 | }; 783 | haveIframe = false; 784 | createIframe = function() { 785 | var myPhotos; 786 | if (haveIframe) { 787 | return; 788 | } 789 | console.log('here', fbg.host, fbg.urlParser.myId()); 790 | myPhotos = $('