├── README ├── .gitignore ├── images ├── don.png ├── bottom.png ├── gear.png ├── logo16.png ├── logout.png ├── scroll.png ├── signup.png ├── loading.gif ├── logo_128.png ├── logo_64.png ├── logo_big.png ├── popup_bg.png ├── ajax-loader.gif ├── bottom_logo.png ├── button_bg.png ├── dashboard.png ├── ic_private.png ├── ic_public.png ├── logo16_anim.gif ├── logo_gray.png ├── logo_large.png ├── logo_small.png ├── popup_logo.png ├── popup_new.png ├── public_bage.png ├── separator.png ├── signup_bg.png ├── create_folder.png ├── generic_file.png ├── logo_anim_new.gif ├── logo_small_bw.png ├── more_content.png ├── upload_button.png ├── btn_camera_gray.png ├── edit_image_logo.png ├── edit_image_panel.png ├── logo_anim_sprite.png ├── take_screenshot.png ├── btn_camera_normal.png ├── choose_gallery_bg.png ├── choose_gallery_new.png ├── dropdown_arrow_up.png ├── dropdown_arrow_down.png └── more_content_pressed.png ├── css ├── chosen-sprite.png ├── reset-min.css ├── options.css ├── reset-context-min.css ├── jquery.jscrollpane.css ├── page.css ├── popup.css └── chosen.css ├── Makefile ├── js ├── minus_auth.js ├── canvas_animation.js ├── jquery.mousewheel.js ├── jquery.timeago.js ├── store.js ├── jquery.tmpl.min.js ├── portamento.js ├── content_script.js ├── popup.js ├── minus.js ├── chosen.jquery.min.js └── background.js ├── config.xml ├── background.html ├── manifest.json ├── message_bridge.js ├── Info.plist ├── includes └── opera.js ├── options.html ├── safari.js ├── popup.html └── edit_image.html /README: -------------------------------------------------------------------------------- 1 | Browser extension for Min.us 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *~ 2 | *.sw* 3 | *sublime* 4 | -------------------------------------------------------------------------------- /images/don.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buger/minus-extension/master/images/don.png -------------------------------------------------------------------------------- /images/bottom.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buger/minus-extension/master/images/bottom.png -------------------------------------------------------------------------------- /images/gear.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buger/minus-extension/master/images/gear.png -------------------------------------------------------------------------------- /images/logo16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buger/minus-extension/master/images/logo16.png -------------------------------------------------------------------------------- /images/logout.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buger/minus-extension/master/images/logout.png -------------------------------------------------------------------------------- /images/scroll.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buger/minus-extension/master/images/scroll.png -------------------------------------------------------------------------------- /images/signup.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buger/minus-extension/master/images/signup.png -------------------------------------------------------------------------------- /images/loading.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buger/minus-extension/master/images/loading.gif -------------------------------------------------------------------------------- /images/logo_128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buger/minus-extension/master/images/logo_128.png -------------------------------------------------------------------------------- /images/logo_64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buger/minus-extension/master/images/logo_64.png -------------------------------------------------------------------------------- /images/logo_big.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buger/minus-extension/master/images/logo_big.png -------------------------------------------------------------------------------- /images/popup_bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buger/minus-extension/master/images/popup_bg.png -------------------------------------------------------------------------------- /css/chosen-sprite.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buger/minus-extension/master/css/chosen-sprite.png -------------------------------------------------------------------------------- /images/ajax-loader.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buger/minus-extension/master/images/ajax-loader.gif -------------------------------------------------------------------------------- /images/bottom_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buger/minus-extension/master/images/bottom_logo.png -------------------------------------------------------------------------------- /images/button_bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buger/minus-extension/master/images/button_bg.png -------------------------------------------------------------------------------- /images/dashboard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buger/minus-extension/master/images/dashboard.png -------------------------------------------------------------------------------- /images/ic_private.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buger/minus-extension/master/images/ic_private.png -------------------------------------------------------------------------------- /images/ic_public.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buger/minus-extension/master/images/ic_public.png -------------------------------------------------------------------------------- /images/logo16_anim.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buger/minus-extension/master/images/logo16_anim.gif -------------------------------------------------------------------------------- /images/logo_gray.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buger/minus-extension/master/images/logo_gray.png -------------------------------------------------------------------------------- /images/logo_large.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buger/minus-extension/master/images/logo_large.png -------------------------------------------------------------------------------- /images/logo_small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buger/minus-extension/master/images/logo_small.png -------------------------------------------------------------------------------- /images/popup_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buger/minus-extension/master/images/popup_logo.png -------------------------------------------------------------------------------- /images/popup_new.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buger/minus-extension/master/images/popup_new.png -------------------------------------------------------------------------------- /images/public_bage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buger/minus-extension/master/images/public_bage.png -------------------------------------------------------------------------------- /images/separator.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buger/minus-extension/master/images/separator.png -------------------------------------------------------------------------------- /images/signup_bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buger/minus-extension/master/images/signup_bg.png -------------------------------------------------------------------------------- /images/create_folder.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buger/minus-extension/master/images/create_folder.png -------------------------------------------------------------------------------- /images/generic_file.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buger/minus-extension/master/images/generic_file.png -------------------------------------------------------------------------------- /images/logo_anim_new.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buger/minus-extension/master/images/logo_anim_new.gif -------------------------------------------------------------------------------- /images/logo_small_bw.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buger/minus-extension/master/images/logo_small_bw.png -------------------------------------------------------------------------------- /images/more_content.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buger/minus-extension/master/images/more_content.png -------------------------------------------------------------------------------- /images/upload_button.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buger/minus-extension/master/images/upload_button.png -------------------------------------------------------------------------------- /images/btn_camera_gray.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buger/minus-extension/master/images/btn_camera_gray.png -------------------------------------------------------------------------------- /images/edit_image_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buger/minus-extension/master/images/edit_image_logo.png -------------------------------------------------------------------------------- /images/edit_image_panel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buger/minus-extension/master/images/edit_image_panel.png -------------------------------------------------------------------------------- /images/logo_anim_sprite.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buger/minus-extension/master/images/logo_anim_sprite.png -------------------------------------------------------------------------------- /images/take_screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buger/minus-extension/master/images/take_screenshot.png -------------------------------------------------------------------------------- /images/btn_camera_normal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buger/minus-extension/master/images/btn_camera_normal.png -------------------------------------------------------------------------------- /images/choose_gallery_bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buger/minus-extension/master/images/choose_gallery_bg.png -------------------------------------------------------------------------------- /images/choose_gallery_new.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buger/minus-extension/master/images/choose_gallery_new.png -------------------------------------------------------------------------------- /images/dropdown_arrow_up.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buger/minus-extension/master/images/dropdown_arrow_up.png -------------------------------------------------------------------------------- /images/dropdown_arrow_down.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buger/minus-extension/master/images/dropdown_arrow_down.png -------------------------------------------------------------------------------- /images/more_content_pressed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buger/minus-extension/master/images/more_content_pressed.png -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | build: 2 | rm -f ext.zip | find . -type d -name .git -prune -o -type f -not \( -name "*.coffee" -o -name "*.less" -o -name "*.sublime*" -o -name ".gitignore" -o -name "*.zip" -o -name "Makefile" \) -print | zip -q ext -@ 3 | 4 | -------------------------------------------------------------------------------- /js/minus_auth.js: -------------------------------------------------------------------------------- 1 | browser.addMessageListener(function(){ 2 | 3 | }); 4 | 5 | try { 6 | var user = document.getElementById('nav_username_display').innerHTML; 7 | } catch(e) { 8 | var user = ""; 9 | } 10 | 11 | browser.onReady(function(){ 12 | browser.postMessage({ method: "setUsername", username: user }) 13 | }); 14 | -------------------------------------------------------------------------------- /config.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | Minus 4 | Minus - Share simply 5 | Minus 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /background.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Minus", 3 | "version": "1.7.98", 4 | "description": "Minus - Share simply", 5 | "icons": { 6 | "16": "images/logo_small.png", 7 | "128": "images/logo_128.png" 8 | }, 9 | "browser_action": { 10 | "default_icon": "images/logo_small.png", 11 | "popup": "popup.html" 12 | }, 13 | "content_scripts": [{ 14 | "css": [ "css/reset-context-min.css", "css/page.css"], 15 | "js": ["js/jquery.min.js", "js/browser_api.js", "js/content_script.js"], 16 | "matches": ["http://*/*","https://*/*"], 17 | "run_at": "document_start" 18 | }], 19 | "background_page": "background.html", 20 | "options_page": "options.html", 21 | "permissions": ["contextMenus", "tabs", "http://*/", "https://*/"] 22 | } 23 | -------------------------------------------------------------------------------- /css/reset-min.css: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2010, Yahoo! Inc. All rights reserved. 3 | Code licensed under the BSD License: 4 | http://developer.yahoo.com/yui/license.html 5 | version: 3.3.0 6 | build: 3167 7 | */ 8 | html{color:#000;background:#FFF;}body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,code,form,fieldset,legend,input,textarea,p,blockquote,th,td{margin:0;padding:0;}table{border-collapse:collapse;border-spacing:0;}fieldset,img{border:0;}address,caption,cite,code,dfn,em,strong,th,var{font-style:normal;font-weight:normal;}li{list-style:none;}caption,th{text-align:left;}h1,h2,h3,h4,h5,h6{font-size:100%;font-weight:normal;}q:before,q:after{content:'';}abbr,acronym{border:0;font-variant:normal;}sup{vertical-align:text-top;}sub{vertical-align:text-bottom;}input,textarea,select{font-family:inherit;font-size:inherit;font-weight:inherit;}input,textarea,select{*font-size:100%;}legend{color:#000;} -------------------------------------------------------------------------------- /css/options.css: -------------------------------------------------------------------------------- 1 | body { 2 | width: 600px; 3 | margin: 0 auto; 4 | padding-top: 50px; 5 | font-family: Helvetica, Arial; 6 | } 7 | 8 | img { 9 | border: 0px !important; 10 | outline: 0px !important; 11 | vertical-align: middle; 12 | } 13 | 14 | .header { 15 | font-size: 36px; 16 | font-family: Arial; 17 | font-weight: bold; 18 | color: rgba(0,0,0,0.6); 19 | } 20 | 21 | .header img { 22 | margin-right: 10px; 23 | } 24 | 25 | .options { 26 | } 27 | 28 | .options h3 { 29 | font-size: 26px; 30 | font-weight: bold; 31 | color: rgba(0,0,0,0.8); 32 | margin-top: 30px; 33 | } 34 | 35 | .options .shortcuts select { 36 | position: absolute; 37 | z-index: 9999; 38 | } 39 | 40 | .options .shortcuts li { 41 | margin-top: 20px; 42 | font-size: 16px; 43 | } 44 | 45 | .options .shortcuts li label { 46 | display: inline-block; 47 | width: 200px; 48 | } 49 | 50 | .options input[type=text] { 51 | width: 20px; 52 | padding: 3px; 53 | } 54 | 55 | .firefox .shortcuts .selected { 56 | display: none; 57 | } 58 | -------------------------------------------------------------------------------- /message_bridge.js: -------------------------------------------------------------------------------- 1 | self.on('message', function(msg) { 2 | var bridge = document.getElementById('ff_message_bridge'); 3 | 4 | if (!bridge) return; 5 | 6 | var _m = document.createElement('textarea'); 7 | _m.className = 'to_page'; 8 | 9 | var message = typeof(msg.message) == "string" ? msg.message : JSON.stringify(msg.message); 10 | _m.innerHTML = message; 11 | bridge.appendChild(_m); 12 | }); 13 | 14 | self.postMessage({ method: "bridge_init" }); 15 | 16 | function checkMessages() { 17 | var bridge = document.getElementById('ff_message_bridge'); 18 | 19 | if (!bridge) return; 20 | 21 | var messages = bridge.querySelectorAll('.from_page'); 22 | var length = messages.length; 23 | 24 | if (length > 0) { 25 | for(var i=0; i frames) { 31 | frame = 0; 32 | } 33 | }; 34 | 35 | var self = this; 36 | 37 | return { 38 | start: function(){ 39 | clearInterval(self.timer); 40 | self.timer = setInterval(draw, 50); 41 | }, 42 | 43 | stop: function(){ 44 | clearInterval(self.timer); 45 | 46 | browser.toolbarItem.setIcon({ path: "images/logo_small.png" }); 47 | 48 | frame = 0; 49 | draw(); 50 | } 51 | }; 52 | }; 53 | -------------------------------------------------------------------------------- /Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Author 6 | Min.us 7 | CFBundleDisplayName 8 | Min.us 9 | CFBundleIdentifier 10 | com.minus.extension 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleShortVersionString 14 | 1 15 | CFBundleVersion 16 | 1 17 | Chrome 18 | 19 | Database Quota 20 | 5242880 21 | Global Page 22 | background.html 23 | Toolbar Items 24 | 25 | 26 | Command 27 | toggle_popup 28 | Identifier 29 | minus_popup 30 | Image 31 | images/logo.png 32 | Label 33 | Min.us 34 | 35 | 36 | 37 | Content 38 | 39 | Scripts 40 | 41 | 42 | Description 43 | Min.us - share simply 44 | ExtensionInfoDictionaryVersion 45 | 1.0 46 | Permissions 47 | 48 | Website Access 49 | 50 | Include Secure Pages 51 | 52 | Level 53 | All 54 | 55 | 56 | Website 57 | http://min.us 58 | 59 | 60 | -------------------------------------------------------------------------------- /css/reset-context-min.css: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2010, Yahoo! Inc. All rights reserved. 3 | Code licensed under the BSD License: 4 | http://developer.yahoo.com/yui/license.html 5 | version: 3.3.0 6 | build: 3167 7 | */ 8 | .yui3-cssreset html{color:#000;background:#FFF;}.yui3-cssreset body,.yui3-cssreset div,.yui3-cssreset dl,.yui3-cssreset dt,.yui3-cssreset dd,.yui3-cssreset ul,.yui3-cssreset ol,.yui3-cssreset li,.yui3-cssreset h1,.yui3-cssreset h2,.yui3-cssreset h3,.yui3-cssreset h4,.yui3-cssreset h5,.yui3-cssreset h6,.yui3-cssreset pre,.yui3-cssreset code,.yui3-cssreset form,.yui3-cssreset fieldset,.yui3-cssreset legend,.yui3-cssreset input,.yui3-cssreset textarea,.yui3-cssreset p,.yui3-cssreset blockquote,.yui3-cssreset th,.yui3-cssreset td{margin:0;padding:0;}.yui3-cssreset table{border-collapse:collapse;border-spacing:0;}.yui3-cssreset fieldset,.yui3-cssreset img{border:0;}.yui3-cssreset address,.yui3-cssreset caption,.yui3-cssreset cite,.yui3-cssreset code,.yui3-cssreset dfn,.yui3-cssreset em,.yui3-cssreset strong,.yui3-cssreset th,.yui3-cssreset var{font-style:normal;font-weight:normal;}.yui3-cssreset li{list-style:none;}.yui3-cssreset caption,.yui3-cssreset th{text-align:left;}.yui3-cssreset h1,.yui3-cssreset h2,.yui3-cssreset h3,.yui3-cssreset h4,.yui3-cssreset h5,.yui3-cssreset h6{font-size:100%;font-weight:normal;}.yui3-cssreset q:before,.yui3-cssreset q:after{content:'';}.yui3-cssreset abbr,.yui3-cssreset acronym{border:0;font-variant:normal;}.yui3-cssreset sup{vertical-align:text-top;}.yui3-cssreset sub{vertical-align:text-bottom;}.yui3-cssreset input,.yui3-cssreset textarea,.yui3-cssreset select{font-family:inherit;font-size:inherit;font-weight:inherit;}.yui3-cssreset input,.yui3-cssreset textarea,.yui3-cssreset select{*font-size:100%;}.yui3-cssreset legend{color:#000;} -------------------------------------------------------------------------------- /css/jquery.jscrollpane.css: -------------------------------------------------------------------------------- 1 | /* 2 | * CSS Styles that are needed by jScrollPane for it to operate correctly. 3 | * 4 | * Include this stylesheet in your site or copy and paste the styles below into your stylesheet - jScrollPane 5 | * may not operate correctly without them. 6 | */ 7 | 8 | .jspContainer 9 | { 10 | overflow: hidden; 11 | position: relative; 12 | } 13 | 14 | .jspPane 15 | { 16 | position: absolute; 17 | width: 100%; 18 | } 19 | 20 | .jspVerticalBar 21 | { 22 | position: absolute; 23 | top: 0; 24 | right: 0; 25 | width: 7px; 26 | height: 100%; 27 | margin-right: 4px; 28 | } 29 | 30 | .jspHorizontalBar 31 | { 32 | position: absolute; 33 | bottom: 0; 34 | left: 0; 35 | width: 100%; 36 | height: 16px; 37 | } 38 | 39 | .jspVerticalBar *, 40 | .jspHorizontalBar * 41 | { 42 | margin: 0; 43 | padding: 0; 44 | } 45 | 46 | .jspCap 47 | { 48 | display: none; 49 | } 50 | 51 | .jspHorizontalBar .jspCap 52 | { 53 | float: left; 54 | } 55 | 56 | .jspTrack 57 | { 58 | margin-top: 10px; 59 | position: relative; 60 | } 61 | 62 | .jspDrag 63 | { 64 | background: #ACACAC; 65 | position: relative; 66 | top: 0; 67 | left: 0; 68 | cursor: pointer; 69 | } 70 | 71 | .jspHorizontalBar .jspTrack, 72 | .jspHorizontalBar .jspDrag 73 | { 74 | float: left; 75 | height: 100%; 76 | } 77 | 78 | .jspArrow 79 | { 80 | background: #50506d; 81 | text-indent: -20000px; 82 | display: block; 83 | cursor: pointer; 84 | } 85 | 86 | .jspArrow.jspDisabled 87 | { 88 | cursor: default; 89 | background: #80808d; 90 | } 91 | 92 | .jspVerticalBar .jspArrow 93 | { 94 | height: 16px; 95 | } 96 | 97 | .jspHorizontalBar .jspArrow 98 | { 99 | width: 16px; 100 | float: left; 101 | height: 100%; 102 | } 103 | 104 | .jspVerticalBar .jspArrow:focus 105 | { 106 | outline: none; 107 | } 108 | 109 | .jspCorner 110 | { 111 | background: #eeeef4; 112 | float: left; 113 | height: 100%; 114 | } 115 | 116 | /* Yuk! CSS Hack for IE6 3 pixel bug :( */ 117 | * html .jspCorner 118 | { 119 | margin: 0 -3px 0 0; 120 | } 121 | -------------------------------------------------------------------------------- /js/jquery.mousewheel.js: -------------------------------------------------------------------------------- 1 | /*! Copyright (c) 2010 Brandon Aaron (http://brandonaaron.net) 2 | * Licensed under the MIT License (LICENSE.txt). 3 | * 4 | * Thanks to: http://adomas.org/javascript-mouse-wheel/ for some pointers. 5 | * Thanks to: Mathias Bank(http://www.mathias-bank.de) for a scope bug fix. 6 | * Thanks to: Seamus Leahy for adding deltaX and deltaY 7 | * 8 | * Version: 3.0.4 9 | * 10 | * Requires: 1.2.2+ 11 | */ 12 | 13 | (function($) { 14 | 15 | var types = ['DOMMouseScroll', 'mousewheel']; 16 | 17 | $.event.special.mousewheel = { 18 | setup: function() { 19 | if ( this.addEventListener ) { 20 | for ( var i=types.length; i; ) { 21 | this.addEventListener( types[--i], handler, false ); 22 | } 23 | } else { 24 | this.onmousewheel = handler; 25 | } 26 | }, 27 | 28 | teardown: function() { 29 | if ( this.removeEventListener ) { 30 | for ( var i=types.length; i; ) { 31 | this.removeEventListener( types[--i], handler, false ); 32 | } 33 | } else { 34 | this.onmousewheel = null; 35 | } 36 | } 37 | }; 38 | 39 | $.fn.extend({ 40 | mousewheel: function(fn) { 41 | return fn ? this.bind("mousewheel", fn) : this.trigger("mousewheel"); 42 | }, 43 | 44 | unmousewheel: function(fn) { 45 | return this.unbind("mousewheel", fn); 46 | } 47 | }); 48 | 49 | 50 | function handler(event) { 51 | var orgEvent = event || window.event, args = [].slice.call( arguments, 1 ), delta = 0, returnValue = true, deltaX = 0, deltaY = 0; 52 | event = $.event.fix(orgEvent); 53 | event.type = "mousewheel"; 54 | 55 | // Old school scrollwheel delta 56 | if ( event.wheelDelta ) { delta = event.wheelDelta/120; } 57 | if ( event.detail ) { delta = -event.detail/3; } 58 | 59 | // New school multidimensional scroll (touchpads) deltas 60 | deltaY = delta; 61 | 62 | // Gecko 63 | if ( orgEvent.axis !== undefined && orgEvent.axis === orgEvent.HORIZONTAL_AXIS ) { 64 | deltaY = 0; 65 | deltaX = -1*delta; 66 | } 67 | 68 | // Webkit 69 | if ( orgEvent.wheelDeltaY !== undefined ) { deltaY = orgEvent.wheelDeltaY/120; } 70 | if ( orgEvent.wheelDeltaX !== undefined ) { deltaX = -1*orgEvent.wheelDeltaX/120; } 71 | 72 | // Add event and delta to the front of the arguments 73 | args.unshift(event, delta, deltaX, deltaY); 74 | 75 | return $.event.handle.apply(this, args); 76 | } 77 | 78 | })(jQuery); -------------------------------------------------------------------------------- /css/page.css: -------------------------------------------------------------------------------- 1 | #minus_drag_area { 2 | position: absolute; 3 | z-index: 99999999; 4 | top: 0px; 5 | left: 0px; 6 | } 7 | 8 | #minus_drag_area .area { 9 | position: absolute; 10 | 11 | top: 100px; 12 | left: 100px; 13 | height: 300px; 14 | width: 300px; 15 | 16 | border: 1px dashed red; 17 | 18 | cursor: move; 19 | 20 | min-width: 30px; 21 | min-height: 30px; 22 | } 23 | 24 | #minus_drag_area .shadow { 25 | position: absolute; 26 | 27 | background-color: #333; 28 | opacity: 0.5; 29 | } 30 | 31 | #minus_drag_area .shadow.top { 32 | top: 0px; 33 | left: 0px; 34 | } 35 | 36 | #minus_drag_area .shadow.left { left: 0px; } 37 | 38 | #minus_drag_area .shadow.top { top: 0px; } 39 | 40 | #minus_drag_area .drag { 41 | position: absolute; 42 | width: 5px; 43 | height: 5px; 44 | border: 2px solid red; 45 | border-radius: 5px; 46 | background: white; 47 | } 48 | 49 | #minus_drag_area .drag.tl { top: -6px; left: -6px; cursor: nw-resize; } 50 | #minus_drag_area .drag.tr { top: -6px; right: -6px; cursor: ne-resize; } 51 | #minus_drag_area .drag.bl { bottom: -6px; left: -6px; cursor: sw-resize; } 52 | #minus_drag_area .drag.br { bottom: -3px; right: -6px; cursor: se-resize; } 53 | 54 | #minus_drag_area .drag.t { top: -6px; cursor: n-resize; } 55 | #minus_drag_area .drag.r { right: -6px; cursor: e-resize; } 56 | #minus_drag_area .drag.l { left: -6px; cursor: w-resize; } 57 | #minus_drag_area .drag.b { bottom: -6px; cursor: s-resize; } 58 | 59 | 60 | #minus_drag_area .size { 61 | position: absolute; 62 | top: -30px; 63 | left: -2px; 64 | 65 | height: 16px; 66 | min-width: 60px; 67 | border: 1px solid #333; 68 | background: #333; 69 | padding: 2px 4px; 70 | 71 | opacity: 0.9; 72 | 73 | color: white; 74 | font-size: 13px; 75 | font-family: Arial; 76 | 77 | border-radius: 3px; 78 | } 79 | 80 | #minus_drag_area .cancel, #minus_drag_area .ok { 81 | position: absolute; 82 | bottom: -25px; 83 | padding: 3px 6px; 84 | 85 | border: 3px; 86 | border: 1px solid #ccc; 87 | 88 | font-size: 14px; 89 | font-family: Arial; 90 | 91 | background: #000; 92 | color: white; 93 | opacity: 0.8; 94 | 95 | cursor: pointer; 96 | } 97 | 98 | #minus_drag_area .cancel:hover, #minus_drag_area .ok:hover { 99 | opacity: 1; 100 | } 101 | 102 | #minus_drag_area .cancel { 103 | right: 80px; 104 | } 105 | 106 | #minus_drag_area .ok { 107 | right: 0px; 108 | } 109 | 110 | -------------------------------------------------------------------------------- /includes/opera.js: -------------------------------------------------------------------------------- 1 | (function(){ 2 | Object.extend = function(destination, source) { 3 | for (var property in source) { 4 | if (source.hasOwnProperty(property)) { 5 | destination[property] = source[property]; 6 | } 7 | } 8 | return destination; 9 | }; 10 | 11 | var background_page; 12 | var loaded_files = []; 13 | 14 | // Fix for jQuery 15 | var navigator = window.navigator; 16 | var location = window.location; 17 | 18 | var browser; 19 | var browser_params = {}; 20 | var jQuery, $; 21 | 22 | window.isContentScript = true; 23 | 24 | function injectJS(script) { 25 | eval(script); 26 | 27 | if (!browser && window.browser) { 28 | browser = window.browser; 29 | 30 | Object.extend(window.browser, browser_params); 31 | } 32 | 33 | if (window.jQuery) { 34 | window.jQuery.noConflict(); 35 | 36 | jQuery = window.jQuery; 37 | 38 | $ = jQuery; 39 | } 40 | } 41 | 42 | function injectCSS(style) { 43 | var scr = document.createElement('style'); 44 | scr.innerHTML = ""; 45 | 46 | document.getElementsByTagName('head')[0].appendChild(scr) 47 | } 48 | 49 | 50 | 51 | var iframe = false; 52 | 53 | try { 54 | window.location.toString() + window.parent.location.toString(); 55 | } catch (e) { 56 | iframe = true; 57 | } 58 | 59 | // Don't load scripts if inside iframe 60 | if (!iframe) { 61 | 62 | opera.postError('Script::Adding on load event'); 63 | 64 | opera.extension.onmessage = function(event){ 65 | if (typeof(event.data) == 'object') { 66 | switch(event.data.method) { 67 | case 'updateState': 68 | break; 69 | 70 | case 'connected': 71 | if (event.data.source == 'background') { 72 | background_page = event.source; 73 | 74 | window.addEventListener('load', function(){ 75 | background_page.postMessage({method:'loadRecources'}); 76 | }, false); 77 | 78 | browser_params._isNetworkInitialized = true; 79 | browser_params._background_page = background_page; 80 | browser_params.extension_url = event.data.extension_url; 81 | browser_params.config = event.data.config; 82 | 83 | opera.postError("Injected script connected: " + JSON.stringify(browser_params)); 84 | } 85 | 86 | break; 87 | 88 | case 'loadRecources': 89 | opera.postError("Loading scripts" + event.data.scripts.length); 90 | 91 | event.data.scripts.forEach(function(script) { 92 | injectJS(script); 93 | }); 94 | 95 | event.data.styles.forEach(function(style) { 96 | injectCSS(style); 97 | }); 98 | 99 | break; 100 | 101 | default: 102 | if (browser) { 103 | opera.postError("Injected script::Received unknown message: " + JSON.stringify(event.data)); 104 | } 105 | } 106 | } 107 | } 108 | } 109 | 110 | })(); 111 | -------------------------------------------------------------------------------- /options.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 |

11 | 12 | Extension configuration 13 |

14 | 15 |
16 |
17 |

Shortcuts

18 |
    19 |
  • 20 | 21 | Ctrl+Alt+ 22 | 23 | 24 |
  • 25 |
  • 26 | 27 | Ctrl+Alt+ 28 | 29 | 30 |
  • 31 |
  • 32 | 33 | Ctrl+Alt+ 34 | 35 | 36 |
  • 37 |
38 |
39 |
40 |
41 | 42 | 43 | 44 | 45 | 98 | 99 | 100 | -------------------------------------------------------------------------------- /js/jquery.timeago.js: -------------------------------------------------------------------------------- 1 | /* 2 | * timeago: a jQuery plugin, version: 0.9.3 (2011-01-21) 3 | * @requires jQuery v1.2.3 or later 4 | * 5 | * Timeago is a jQuery plugin that makes it easy to support automatically 6 | * updating fuzzy timestamps (e.g. "4 minutes ago" or "about 1 day ago"). 7 | * 8 | * For usage and examples, visit: 9 | * http://timeago.yarp.com/ 10 | * 11 | * Licensed under the MIT: 12 | * http://www.opensource.org/licenses/mit-license.php 13 | * 14 | * Copyright (c) 2008-2011, Ryan McGeary (ryanonjavascript -[at]- mcgeary [*dot*] org) 15 | */ 16 | (function($) { 17 | $.timeago = function(timestamp) { 18 | if (timestamp instanceof Date) { 19 | return inWords(timestamp); 20 | } else if (typeof timestamp === "string") { 21 | return inWords($.timeago.parse(timestamp)); 22 | } else { 23 | return inWords($.timeago.datetime(timestamp)); 24 | } 25 | }; 26 | var $t = $.timeago; 27 | 28 | $.extend($.timeago, { 29 | settings: { 30 | refreshMillis: 60000, 31 | allowFuture: false, 32 | strings: { 33 | prefixAgo: null, 34 | prefixFromNow: null, 35 | suffixAgo: "ago", 36 | suffixFromNow: "from now", 37 | seconds: "less than a minute", 38 | minute: "about a minute", 39 | minutes: "%d minutes", 40 | hour: "about an hour", 41 | hours: "about %d hours", 42 | day: "a day", 43 | days: "%d days", 44 | month: "about a month", 45 | months: "%d months", 46 | year: "about a year", 47 | years: "%d years", 48 | numbers: [] 49 | } 50 | }, 51 | inWords: function(distanceMillis) { 52 | var $l = this.settings.strings; 53 | var prefix = $l.prefixAgo; 54 | var suffix = $l.suffixAgo; 55 | if (this.settings.allowFuture) { 56 | if (distanceMillis < 0) { 57 | prefix = $l.prefixFromNow; 58 | suffix = $l.suffixFromNow; 59 | } 60 | distanceMillis = Math.abs(distanceMillis); 61 | } 62 | 63 | var seconds = distanceMillis / 1000; 64 | var minutes = seconds / 60; 65 | var hours = minutes / 60; 66 | var days = hours / 24; 67 | var years = days / 365; 68 | 69 | function substitute(stringOrFunction, number) { 70 | var string = $.isFunction(stringOrFunction) ? stringOrFunction(number, distanceMillis) : stringOrFunction; 71 | var value = ($l.numbers && $l.numbers[number]) || number; 72 | return string.replace(/%d/i, value); 73 | } 74 | 75 | var words = seconds < 45 && substitute($l.seconds, Math.round(seconds)) || 76 | seconds < 90 && substitute($l.minute, 1) || 77 | minutes < 45 && substitute($l.minutes, Math.round(minutes)) || 78 | minutes < 90 && substitute($l.hour, 1) || 79 | hours < 24 && substitute($l.hours, Math.round(hours)) || 80 | hours < 48 && substitute($l.day, 1) || 81 | days < 30 && substitute($l.days, Math.floor(days)) || 82 | days < 60 && substitute($l.month, 1) || 83 | days < 365 && substitute($l.months, Math.floor(days / 30)) || 84 | years < 2 && substitute($l.year, 1) || 85 | substitute($l.years, Math.floor(years)); 86 | 87 | return $.trim([prefix, words, suffix].join(" ")); 88 | }, 89 | parse: function(iso8601) { 90 | var s = $.trim(iso8601); 91 | s = s.replace(/\.\d\d\d+/,""); // remove milliseconds 92 | s = s.replace(/-/,"/").replace(/-/,"/"); 93 | s = s.replace(/T/," ").replace(/Z/," UTC"); 94 | s = s.replace(/([\+\-]\d\d)\:?(\d\d)/," $1$2"); // -04:00 -> -0400 95 | return new Date(s); 96 | }, 97 | datetime: function(elem) { 98 | // jQuery's `is()` doesn't play well with HTML5 in IE 99 | var isTime = $(elem).get(0).tagName.toLowerCase() === "time"; // $(elem).is("time"); 100 | var iso8601 = isTime ? $(elem).attr("datetime") : $(elem).attr("title"); 101 | return $t.parse(iso8601); 102 | } 103 | }); 104 | 105 | $.fn.timeago = function() { 106 | var self = this; 107 | self.each(refresh); 108 | 109 | var $s = $t.settings; 110 | if ($s.refreshMillis > 0) { 111 | setInterval(function() { self.each(refresh); }, $s.refreshMillis); 112 | } 113 | return self; 114 | }; 115 | 116 | function refresh() { 117 | var data = prepareData(this); 118 | if (!isNaN(data.datetime)) { 119 | $(this).text(inWords(data.datetime)); 120 | } 121 | return this; 122 | } 123 | 124 | function prepareData(element) { 125 | element = $(element); 126 | if (!element.data("timeago")) { 127 | element.data("timeago", { datetime: $t.datetime(element) }); 128 | var text = $.trim(element.text()); 129 | if (text.length > 0) { 130 | element.attr("title", text); 131 | } 132 | } 133 | return element.data("timeago"); 134 | } 135 | 136 | function inWords(date) { 137 | return $t.inWords(distance(date)); 138 | } 139 | 140 | function distance(date) { 141 | return (new Date().getTime() - date.getTime()); 142 | } 143 | 144 | // fix for IE6 suckage 145 | document.createElement("abbr"); 146 | document.createElement("time"); 147 | }(jQuery)); 148 | -------------------------------------------------------------------------------- /js/store.js: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2010-2011 Marcus Westin 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining a copy 4 | * of this software and associated documentation files (the "Software"), to deal 5 | * in the Software without restriction, including without limitation the rights 6 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | * copies of the Software, and to permit persons to whom the Software is 8 | * furnished to do so, subject to the following conditions: 9 | * 10 | * The above copyright notice and this permission notice shall be included in 11 | * all copies or substantial portions of the Software. 12 | * 13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | * THE SOFTWARE. 20 | */ 21 | 22 | var store = (function(){ 23 | var api = {}, 24 | win = window, 25 | doc = win.document, 26 | localStorageName = 'localStorage', 27 | globalStorageName = 'globalStorage', 28 | namespace = '__storejs__', 29 | storage 30 | 31 | api.disabled = false 32 | api.set = function(key, value) {} 33 | api.get = function(key) {} 34 | api.remove = function(key) {} 35 | api.clear = function() {} 36 | api.transact = function(key, transactionFn) { 37 | var val = api.get(key) 38 | if (typeof val == 'undefined') { val = {} } 39 | transactionFn(val) 40 | api.set(key, val) 41 | } 42 | 43 | api.serialize = function(value) { 44 | return JSON.stringify(value) 45 | } 46 | api.deserialize = function(value) { 47 | if (typeof value === "undefined" || typeof value != 'string' || value === "undefined" || value === "null") { return undefined } 48 | return JSON.parse(value) 49 | } 50 | 51 | // Functions to encapsulate questionable FireFox 3.6.13 behavior 52 | // when about.config::dom.storage.enabled === false 53 | // See https://github.com/marcuswestin/store.js/issues#issue/13 54 | function isLocalStorageNameSupported() { 55 | try { return (localStorageName in win && win[localStorageName]) } 56 | catch(err) { return false } 57 | } 58 | 59 | function isGlobalStorageNameSupported() { 60 | try { return (globalStorageName in win && win[globalStorageName] && win[globalStorageName][win.location.hostname]) } 61 | catch(err) { return false } 62 | } 63 | 64 | if (isLocalStorageNameSupported()) { 65 | storage = win[localStorageName] 66 | api.set = function(key, val) { 67 | if (typeof val === "undefined" || val === null) 68 | api.remove(key) 69 | else 70 | storage.setItem(key, api.serialize(val)) 71 | } 72 | api.get = function(key) { return api.deserialize(storage.getItem(key)) } 73 | api.remove = function(key) { storage.removeItem(key) } 74 | api.clear = function() { storage.clear() } 75 | 76 | } else if (isGlobalStorageNameSupported()) { 77 | storage = win[globalStorageName][win.location.hostname] 78 | api.set = function(key, val) { storage[key] = api.serialize(val) } 79 | api.get = function(key) { return api.deserialize(storage[key] && storage[key].value) } 80 | api.remove = function(key) { delete storage[key] } 81 | api.clear = function() { for (var key in storage ) { delete storage[key] } } 82 | 83 | } else if (doc.documentElement.addBehavior) { 84 | var storage = doc.createElement('div') 85 | function withIEStorage(storeFunction) { 86 | return function() { 87 | var args = Array.prototype.slice.call(arguments, 0) 88 | args.unshift(storage) 89 | // See http://msdn.microsoft.com/en-us/library/ms531081(v=VS.85).aspx 90 | // and http://msdn.microsoft.com/en-us/library/ms531424(v=VS.85).aspx 91 | doc.body.appendChild(storage) 92 | storage.addBehavior('#default#userData') 93 | storage.load(localStorageName) 94 | var result = storeFunction.apply(api, args) 95 | doc.body.removeChild(storage) 96 | return result 97 | } 98 | } 99 | api.set = withIEStorage(function(storage, key, val) { 100 | storage.setAttribute(key, api.serialize(val)) 101 | storage.save(localStorageName) 102 | }) 103 | api.get = withIEStorage(function(storage, key) { 104 | return api.deserialize(storage.getAttribute(key)) 105 | }) 106 | api.remove = withIEStorage(function(storage, key) { 107 | storage.removeAttribute(key) 108 | storage.save(localStorageName) 109 | }) 110 | api.clear = withIEStorage(function(storage) { 111 | var attributes = storage.XMLDocument.documentElement.attributes 112 | storage.load(localStorageName) 113 | for (var i=0, attr; attr = attributes[i]; i++) { 114 | storage.removeAttribute(attr.name) 115 | } 116 | storage.save(localStorageName) 117 | }) 118 | } 119 | 120 | try { 121 | api.set(namespace, namespace) 122 | if (api.get(namespace) != namespace) { api.disabled = true } 123 | api.remove(namespace) 124 | } catch(e) { 125 | api.disabled = true 126 | } 127 | 128 | return api 129 | })(); 130 | 131 | if (typeof module != 'undefined') { module.exports = store } 132 | -------------------------------------------------------------------------------- /safari.js: -------------------------------------------------------------------------------- 1 | (function(){ 2 | if (window.top === window) { 3 | var listener; 4 | 5 | function togglePopup(popup_url) { 6 | var extension_id = safari.extension.baseURI.match(/safari-extension\:\/\/([^\/]*).*/)[1]; 7 | var popup = document.getElementById(extension_id + '_popup'); 8 | 9 | if (!popup) { 10 | if (!document.body) { 11 | if (!listener) { 12 | listener = setInterval(function() { 13 | if (document.body && !document.getElementById(extension_id + '_popup')) { 14 | togglePopup(); 15 | 16 | clearInterval(listener); 17 | } 18 | }, 50); 19 | } 20 | 21 | return; 22 | } 23 | 24 | clearInterval(listener); 25 | 26 | var style = document.createElement('style'); 27 | style.innerHTML = ".ext_popup { position: fixed; overflow: hidden; top: 0px; left: 0px; z-index: 2147483646; border: 0; -webkit-box-shadow: 0px 0px 5px 5px #888; box-shadow: 0px 0px 5px 5px #888;}"; 28 | document.body.insertBefore(style, document.body.firstChild); 29 | 30 | var iframe = document.createElement('iframe'); 31 | iframe.id = extension_id + "_popup"; 32 | iframe.src = safari.extension.baseURI + popup_url; 33 | iframe.scrolling = 'none'; 34 | iframe.frameborder = '0'; 35 | iframe.className = "ext_popup"; 36 | iframe.setAttribute('allowtransparency', "true"); 37 | 38 | document.body.insertBefore(iframe, document.body.firstChild); 39 | 40 | popup = document.getElementById(extension_id + '_popup'); 41 | 42 | document.addEventListener('click', function () { 43 | console.log('clicked'); 44 | 45 | popup.style.display = 'none'; 46 | }); 47 | } else { 48 | if (popup.style.display == 'none') { 49 | popup.src = popup.src; 50 | popup.width = 0; 51 | popup.height = 0; 52 | popup.style.display = 'block'; 53 | } else { 54 | popup.style.display = 'none'; 55 | } 56 | } 57 | } 58 | 59 | function injectJS(script) { 60 | eval(script); 61 | } 62 | 63 | function injectCSS(style) { 64 | var scr = document.createElement('style'); 65 | scr.innerHTML = style; 66 | 67 | document.getElementsByTagName('head')[0].appendChild(scr) 68 | } 69 | 70 | safari.self.addEventListener("message", function (event) { 71 | if (event.name == "_message") { 72 | if (event.message.method == "loadRecources") { 73 | console.log("Loading recources:", event.message); 74 | 75 | event.message.scripts.forEach(function(script) { 76 | injectJS(script); 77 | }); 78 | 79 | if (window.jQuery) { 80 | window.jQuery.noConflict(); 81 | } 82 | 83 | event.message.styles.forEach(function(style) { 84 | injectCSS(style); 85 | }); 86 | } 87 | } else if (event.name == "toggle_popup") { 88 | console.log("Toggling popup"); 89 | 90 | togglePopup(event.message.popup_url); 91 | } 92 | }, false); 93 | 94 | window.addEventListener('DOMContentLoaded', function(){ 95 | console.log("onLoad event"); 96 | 97 | safari.self.tab.dispatchMessage("_message", {method:'loadRecources'}); 98 | }, false); 99 | 100 | window.addEventListener('unload', function(){ 101 | safari.self.tab.dispatchMessage("disconnect", {method:'loadRecources'}); 102 | }, false); 103 | 104 | window.addEventListener("message", function(event){ 105 | if (event.origin.match(/^safari-extension:\/\/.*/)){ 106 | var extension_id = safari.extension.baseURI.match(/safari-extension\:\/\/([^\/]*).*/)[1]; 107 | var popup = document.getElementById(extension_id + '_popup'); 108 | 109 | popup.width = event.data.width+5; 110 | popup.height = event.data.height+5; 111 | } 112 | }, false); 113 | 114 | function handleContextMenu(event) { 115 | var info = { 116 | nodeName: event.target.nodeName, 117 | srcUrl: event.target.src 118 | }; 119 | safari.self.tab.setContextMenuEventUserInfo(event, info); 120 | } 121 | document.addEventListener("contextmenu", handleContextMenu, false); 122 | } 123 | })(); 124 | -------------------------------------------------------------------------------- /js/jquery.tmpl.min.js: -------------------------------------------------------------------------------- 1 | (function(a){var r=a.fn.domManip,d="_tmplitem",q=/^[^<]*(<[\w\W]+>)[^>]*$|\{\{\! /,b={},f={},e,p={key:0,data:{}},h=0,c=0,l=[];function g(e,d,g,i){var c={data:i||(d?d.data:{}),_wrap:d?d._wrap:null,tmpl:null,parent:d||null,nodes:[],calls:u,nest:w,wrap:x,html:v,update:t};e&&a.extend(c,e,{nodes:[],parent:d});if(g){c.tmpl=g;c._ctnt=c._ctnt||c.tmpl(a,c);c.key=++h;(l.length?f:b)[h]=c}return c}a.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(f,d){a.fn[f]=function(n){var g=[],i=a(n),k,h,m,l,j=this.length===1&&this[0].parentNode;e=b||{};if(j&&j.nodeType===11&&j.childNodes.length===1&&i.length===1){i[d](this[0]);g=this}else{for(h=0,m=i.length;h0?this.clone(true):this).get();a.fn[d].apply(a(i[h]),k);g=g.concat(k)}c=0;g=this.pushStack(g,f,i.selector)}l=e;e=null;a.tmpl.complete(l);return g}});a.fn.extend({tmpl:function(d,c,b){return a.tmpl(this[0],d,c,b)},tmplItem:function(){return a.tmplItem(this[0])},template:function(b){return a.template(b,this[0])},domManip:function(d,l,j){if(d[0]&&d[0].nodeType){var f=a.makeArray(arguments),g=d.length,i=0,h;while(i1)f[0]=[a.makeArray(d)];if(h&&c)f[2]=function(b){a.tmpl.afterManip(this,b,j)};r.apply(this,f)}else r.apply(this,arguments);c=0;!e&&a.tmpl.complete(b);return this}});a.extend({tmpl:function(d,h,e,c){var j,k=!c;if(k){c=p;d=a.template[d]||a.template(null,d);f={}}else if(!d){d=c.tmpl;b[c.key]=c;c.nodes=[];c.wrapped&&n(c,c.wrapped);return a(i(c,null,c.tmpl(a,c)))}if(!d)return[];if(typeof h==="function")h=h.call(c||{});e&&e.wrapped&&n(e,e.wrapped);j=a.isArray(h)?a.map(h,function(a){return a?g(e,c,d,a):null}):[g(e,c,d,h)];return k?a(i(c,null,j)):j},tmplItem:function(b){var c;if(b instanceof a)b=b[0];while(b&&b.nodeType===1&&!(c=a.data(b,"tmplItem"))&&(b=b.parentNode));return c||p},template:function(c,b){if(b){if(typeof b==="string")b=o(b);else if(b instanceof a)b=b[0]||{};if(b.nodeType)b=a.data(b,"tmpl")||a.data(b,"tmpl",o(b.innerHTML));return typeof c==="string"?(a.template[c]=b):b}return c?typeof c!=="string"?a.template(null,c):a.template[c]||a.template(null,q.test(c)?c:a(c)):null},encode:function(a){return(""+a).split("<").join("<").split(">").join(">").split('"').join(""").split("'").join("'")}});a.extend(a.tmpl,{tag:{tmpl:{_default:{$2:"null"},open:"if($notnull_1){_=_.concat($item.nest($1,$2));}"},wrap:{_default:{$2:"null"},open:"$item.calls(_,$1,$2);_=[];",close:"call=$item.calls();_=call._.concat($item.wrap(call,_));"},each:{_default:{$2:"$index, $value"},open:"if($notnull_1){$.each($1a,function($2){with(this){",close:"}});}"},"if":{open:"if(($notnull_1) && $1a){",close:"}"},"else":{_default:{$1:"true"},open:"}else if(($notnull_1) && $1a){"},html:{open:"if($notnull_1){_.push($1a);}"},"=":{_default:{$1:"$data"},open:"if($notnull_1){_.push($.encode($1a));}"},"!":{open:""}},complete:function(){b={}},afterManip:function(f,b,d){var e=b.nodeType===11?a.makeArray(b.childNodes):b.nodeType===1?[b]:[];d.call(f,b);m(e);c++}});function i(e,g,f){var b,c=f?a.map(f,function(a){return typeof a==="string"?e.key?a.replace(/(<\w+)(?=[\s>])(?![^>]*_tmplitem)([^>]*)/g,"$1 "+d+'="'+e.key+'" $2'):a:i(a,e,a._ctnt)}):e;if(g)return c;c=c.join("");c.replace(/^\s*([^<\s][^<]*)?(<[\w\W]+>)([^>]*[^>\s])?\s*$/,function(f,c,e,d){b=a(e).get();m(b);if(c)b=j(c).concat(b);if(d)b=b.concat(j(d))});return b?b:j(c)}function j(c){var b=document.createElement("div");b.innerHTML=c;return a.makeArray(b.childNodes)}function o(b){return new Function("jQuery","$item","var $=jQuery,call,_=[],$data=$item.data;with($data){_.push('"+a.trim(b).replace(/([\\'])/g,"\\$1").replace(/[\r\t\n]/g," ").replace(/\$\{([^\}]*)\}/g,"{{= $1}}").replace(/\{\{(\/?)(\w+|.)(?:\(((?:[^\}]|\}(?!\}))*?)?\))?(?:\s+(.*?)?)?(\(((?:[^\}]|\}(?!\}))*?)\))?\s*\}\}/g,function(m,l,j,d,b,c,e){var i=a.tmpl.tag[j],h,f,g;if(!i)throw"Template command not found: "+j;h=i._default||[];if(c&&!/\w$/.test(b)){b+=c;c=""}if(b){b=k(b);e=e?","+k(e)+")":c?")":"";f=c?b.indexOf(".")>-1?b+c:"("+b+").call($item"+e:b;g=c?f:"(typeof("+b+")==='function'?("+b+").call($item):("+b+"))"}else g=f=h.$1||"null";d=k(d);return"');"+i[l?"close":"open"].split("$notnull_1").join(b?"typeof("+b+")!=='undefined' && ("+b+")!=null":"true").split("$1a").join(g).split("$1").join(f).split("$2").join(d?d.replace(/\s*([^\(]+)\s*(\((.*?)\))?/g,function(d,c,b,a){a=a?","+a+")":b?")":"";return a?"("+c+").call($item"+a:d}):h.$2||"")+"_.push('"})+"');}return _;")}function n(c,b){c._wrap=i(c,true,a.isArray(b)?b:[q.test(b)?b:a(b).html()]).join("")}function k(a){return a?a.replace(/\\'/g,"'").replace(/\\\\/g,"\\"):null}function s(b){var a=document.createElement("div");a.appendChild(b.cloneNode(true));return a.innerHTML}function m(o){var n="_"+c,k,j,l={},e,p,i;for(e=0,p=o.length;e=0;i--)m(j[i]);m(k)}function m(j){var p,i=j,k,e,m;if(m=j.getAttribute(d)){while(i.parentNode&&(i=i.parentNode).nodeType===1&&!(p=i.getAttribute(d)));if(p!==m){i=i.parentNode?i.nodeType===11?0:i.getAttribute(d)||0:0;if(!(e=b[m])){e=f[m];e=g(e,b[i]||f[i],null,true);e.key=++h;b[h]=e}c&&o(m)}j.removeAttribute(d)}else if(c&&(e=a.data(j,"tmplItem"))){o(e.key);b[e.key]=e;i=a.data(j.parentNode,"tmplItem");i=i?i.key:0}if(e){k=e;while(k&&k.key!=i){k.nodes.push(j);k=k.parent}delete e._ctnt;delete e._wrap;a.data(j,"tmplItem",e)}function o(a){a=a+n;e=l[a]=l[a]||g(e,b[e.parent.key+n]||e.parent,null,true)}}}function u(a,d,c,b){if(!a)return l.pop();l.push({_:a,tmpl:d,item:this,data:c,options:b})}function w(d,c,b){return a.tmpl(a.template(d),c,b,this)}function x(b,d){var c=b.options||{};c.wrapped=d;return a.tmpl(a.template(b.tmpl),b.data,c,b.item)}function v(d,c){var b=this._wrap;return a.map(a(a.isArray(b)?b.join(""):b).filter(d||"*"),function(a){return c?a.innerText||a.textContent:a.outerHTML||s(a)})}function t(){var b=this.nodes;a.tmpl(null,null,null,this).insertBefore(b[0]);a(b).remove()}})(jQuery) -------------------------------------------------------------------------------- /popup.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 69 | 70 | 71 | 98 | 99 | 100 |
101 | 134 | 135 |
136 | Dashboard 137 | 138 | My Files 139 | 142 |
143 | 144 |
145 |
    146 |
  • 147 |
148 |
149 | 156 |
157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | -------------------------------------------------------------------------------- /js/portamento.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * 3 | * Portamento v1.1 - 2011-07-20 4 | * http://simianstudios.com/portamento 5 | * 6 | */ 7 | /** 8 | * 9 | * Creates a sliding panel that respects the boundaries of 10 | * a given wrapper, and also has sensible behaviour if the 11 | * viewport is too small to display the whole panel. 12 | * 13 | * ---- 14 | * 15 | * Uses the viewportOffset plugin by Ben Alman aka Cowboy: 16 | * http://benalman.com/projects/jquery-misc-plugins/#viewportoffset 17 | * 18 | * Uses a portion of CFT by Juriy Zaytsev aka Kangax: 19 | * http://kangax.github.com/cft/#IS_POSITION_FIXED_SUPPORTED 20 | * 21 | * Uses code by Matthew Eernisse: 22 | * http://www.fleegix.org/articles/2006-05-30-getting-the-scrollbar-width-in-pixels 23 | * 24 | * Builds on work by Remy Sharp: 25 | * http://jqueryfordesigners.com/fixed-floating-elements/ 26 | * 27 | * ---- 28 | * 29 | * Copyright 2011 Kris Noble except where noted. 30 | * Licensed under the GPLv3 license: 31 | * http://www.gnu.org/licenses/gpl-3.0.txt 32 | * 33 | */ 34 | (function($){ 35 | 36 | $.fn.portamento = function(options) { 37 | 38 | // we'll use the window and document objects a lot, so 39 | // saving them as variables now saves a lot of function calls 40 | var thisWindow = $(window); 41 | var thisDocument = $(document); 42 | 43 | /** 44 | * NOTE by Kris - included here so as to avoid namespace clashes. 45 | * 46 | * jQuery viewportOffset - v0.3 - 2/3/2010 47 | * http://benalman.com/projects/jquery-misc-plugins/ 48 | * 49 | * Copyright (c) 2010 "Cowboy" Ben Alman 50 | * Dual licensed under the MIT and GPL licenses. 51 | * http://benalman.com/about/license/ 52 | */ 53 | $.fn.viewportOffset = function() { 54 | var win = $(window); 55 | var offset = $(this).offset(); 56 | 57 | return { 58 | left: offset.left - win.scrollLeft(), 59 | top: offset.top - win.scrollTop() 60 | }; 61 | }; 62 | 63 | /** 64 | * 65 | * A test to see if position:fixed is supported. 66 | * Taken from CFT by Kangax - http://kangax.github.com/cft/#IS_POSITION_FIXED_SUPPORTED 67 | * Included here so as to avoid namespace clashes. 68 | * 69 | */ 70 | function positionFixedSupported () { 71 | var container = document.body; 72 | if (document.createElement && container && container.appendChild && container.removeChild) { 73 | var el = document.createElement("div"); 74 | if (!el.getBoundingClientRect) { 75 | return null; 76 | } 77 | el.innerHTML = "x"; 78 | el.style.cssText = "position:fixed;top:100px;"; 79 | container.appendChild(el); 80 | var originalHeight = container.style.height, originalScrollTop = container.scrollTop; 81 | container.style.height = "3000px"; 82 | container.scrollTop = 500; 83 | var elementTop = el.getBoundingClientRect().top; 84 | container.style.height = originalHeight; 85 | var isSupported = elementTop === 100; 86 | container.removeChild(el); 87 | container.scrollTop = originalScrollTop; 88 | return isSupported; 89 | } 90 | return null; 91 | } 92 | 93 | /** 94 | * 95 | * Get the scrollbar width by Matthew Eernisse. 96 | * http://www.fleegix.org/articles/2006-05-30-getting-the-scrollbar-width-in-pixels 97 | * Included here so as to avoid namespace clashes. 98 | * 99 | */ 100 | function getScrollerWidth() { 101 | var scr = null; 102 | var inn = null; 103 | var wNoScroll = 0; 104 | var wScroll = 0; 105 | 106 | // Outer scrolling div 107 | scr = document.createElement('div'); 108 | scr.style.position = 'absolute'; 109 | scr.style.top = '-1000px'; 110 | scr.style.left = '-1000px'; 111 | scr.style.width = '100px'; 112 | scr.style.height = '50px'; 113 | // Start with no scrollbar 114 | scr.style.overflow = 'hidden'; 115 | 116 | // Inner content div 117 | inn = document.createElement('div'); 118 | inn.style.width = '100%'; 119 | inn.style.height = '200px'; 120 | 121 | // Put the inner div in the scrolling div 122 | scr.appendChild(inn); 123 | // Append the scrolling div to the doc 124 | document.body.appendChild(scr); 125 | 126 | // Width of the inner div sans scrollbar 127 | wNoScroll = inn.offsetWidth; 128 | // Add the scrollbar 129 | scr.style.overflow = 'auto'; 130 | // Width of the inner div width scrollbar 131 | wScroll = inn.offsetWidth; 132 | 133 | // Remove the scrolling div from the doc 134 | document.body.removeChild(document.body.lastChild); 135 | 136 | // Pixel width of the scroller 137 | return (wNoScroll - wScroll); 138 | } 139 | 140 | // --------------------------------------------------------------------------------------------------- 141 | 142 | // get the definitive options 143 | var opts = $.extend({}, $.fn.portamento.defaults, options); 144 | 145 | // setup the vars accordingly 146 | var panel = this; 147 | var wrapper = opts.wrapper; 148 | var gap = opts.gap; 149 | var disableWorkaround = opts.disableWorkaround; 150 | var fullyCapableBrowser = positionFixedSupported(); 151 | 152 | if(panel.length != 1) { 153 | // die gracefully if the user has tried to pass multiple elements 154 | // (multiple element support is on the TODO list!) or no elements... 155 | return this; 156 | } 157 | 158 | if(!fullyCapableBrowser && disableWorkaround) { 159 | // just stop here, as the dev doesn't want to use the workaround 160 | return this; 161 | } 162 | 163 | // wrap the floating panel in a div, then set a sensible min-height and width 164 | panel.wrap('
'); 165 | var float_container = $('#portamento_container'); 166 | float_container.css({ 167 | 'min-height': panel.outerHeight(), 168 | 'width': panel.outerWidth() 169 | }); 170 | 171 | // calculate the upper scrolling boundary 172 | var panelOffset = panel.offset().top; 173 | var panelMargin = parseFloat(panel.css('marginTop').replace(/auto/, 0)); 174 | var realPanelOffset = panelOffset - panelMargin; 175 | var topScrollBoundary = realPanelOffset - gap; 176 | 177 | // a couple of numbers to account for margins and padding on the relevant elements 178 | var wrapperPaddingFix = parseFloat(wrapper.css('paddingTop').replace(/auto/, 0)); 179 | var containerMarginFix = parseFloat(float_container.css('marginTop').replace(/auto/, 0)); 180 | 181 | // do some work to fix IE misreporting the document width 182 | var ieFix = 0; 183 | 184 | var isMSIE = /*@cc_on!@*/0; 185 | 186 | if (isMSIE) { 187 | ieFix = getScrollerWidth() + 4; 188 | } 189 | 190 | // --------------------------------------------------------------------------------------------------- 191 | 192 | thisWindow.bind("scroll.portamento", function () { 193 | 194 | if(thisWindow.height() > panel.outerHeight() && thisWindow.width() >= (thisDocument.width() - ieFix)) { // don't scroll if the window isn't big enough 195 | 196 | var y = thisDocument.scrollTop(); // current scroll position of the document 197 | 198 | if (y >= (topScrollBoundary)) { // if we're at or past the upper scrolling boundary 199 | if((panel.innerHeight() - wrapper.viewportOffset().top) - wrapperPaddingFix + gap >= wrapper.height()) { // if we're at or past the bottom scrolling boundary 200 | if(panel.hasClass('fixed') || thisWindow.height() >= panel.outerHeight()) { // check that there's work to do 201 | panel.removeClass('fixed'); 202 | panel.css('top', (wrapper.height() - panel.innerHeight()) + 'px'); 203 | } 204 | } else { // if we're somewhere in the middle 205 | panel.addClass('fixed'); 206 | 207 | if(fullyCapableBrowser) { // supports position:fixed 208 | panel.css('top', gap + 'px'); // to keep the gap 209 | } else { 210 | panel.clearQueue(); 211 | panel.css('position', 'absolute').animate({top: (0 - float_container.viewportOffset().top + gap)}); 212 | } 213 | } 214 | } else { 215 | // if we're above the top scroll boundary 216 | panel.removeClass('fixed'); 217 | panel.css('top', '0'); // remove any added gap 218 | } 219 | } else { 220 | panel.removeClass('fixed'); 221 | } 222 | }); 223 | 224 | // --------------------------------------------------------------------------------------------------- 225 | 226 | thisWindow.bind("resize.portamento", function () { 227 | // stop users getting undesirable behaviour if they resize the window too small 228 | if(thisWindow.height() <= panel.outerHeight() || thisWindow.width() < thisDocument.width()) { 229 | if(panel.hasClass('fixed')) { 230 | panel.removeClass('fixed'); 231 | panel.css('top', '0'); 232 | } 233 | } else { 234 | thisWindow.trigger('scroll.portamento'); // trigger the scroll event to place the panel correctly 235 | } 236 | }); 237 | 238 | // --------------------------------------------------------------------------------------------------- 239 | 240 | thisWindow.bind("orientationchange.portamento", function () { 241 | // if device orientation changes, trigger the resize event 242 | thisWindow.trigger('resize.portamento'); 243 | }); 244 | 245 | // --------------------------------------------------------------------------------------------------- 246 | 247 | // trigger the scroll event immediately so that the panel is positioned correctly if the page loads anywhere other than the top. 248 | thisWindow.trigger('scroll.portamento'); 249 | 250 | // return this to maintain chainability 251 | return this; 252 | }; 253 | 254 | // set some sensible defaults 255 | $.fn.portamento.defaults = { 256 | 'wrapper' : $('body'), // the element that will act as the sliding panel's boundaries 257 | 'gap' : 10, // the gap (in pixels) left between the top of the viewport and the top of the panel 258 | 'disableWorkaround' : false // option to disable the workaround for not-quite capable browsers 259 | }; 260 | 261 | })(jQuery); -------------------------------------------------------------------------------- /js/content_script.js: -------------------------------------------------------------------------------- 1 | if (!$('html').attr('minus_screen_capture_injected')) 2 | { 3 | $('html').attr('minus_screen_capture_injected', true); 4 | 5 | var saved_scroll; 6 | var scroll_position; 7 | 8 | (function($){ 9 | 10 | $.fn.disableSelection = function() { 11 | return this.each(function() { 12 | $(this).attr('unselectable', 'on') 13 | .css({ 14 | '-moz-user-select':'none', 15 | '-webkit-user-select':'none', 16 | 'user-select':'none' 17 | }) 18 | .each(function() { 19 | this.onselectstart = function() { return false; }; 20 | }); 21 | }); 22 | }; 23 | 24 | })(jQuery); 25 | 26 | function initializeDrag(){ 27 | var template = [ 28 | ''].join(''); 51 | 52 | var container = $(template).appendTo(document.body); 53 | container.css({ visibility: "hidden" }); 54 | container.show(); 55 | 56 | console.log('initializing drag'); 57 | 58 | container.find('*').disableSelection(); 59 | 60 | container.css({ width: document.width, height:document.height }); 61 | 62 | var draggable = container.find('.area'); 63 | draggable.css({ left: (document.width/2 - 150), top: (document.body.scrollTop+200) }); 64 | 65 | var shadow_top = container.find('.shadow.top')[0], 66 | shadow_left = container.find('.shadow.left')[0], 67 | shadow_right = container.find('.shadow.right')[0], 68 | shadow_bottom = container.find('.shadow.bottom')[0], 69 | 70 | drag_t = container.find('.drag.t')[0], 71 | drag_b = container.find('.drag.b')[0], 72 | drag_r = container.find('.drag.r')[0], 73 | drag_l = container.find('.drag.l')[0]; 74 | 75 | function updateShadow(){ 76 | var offset = draggable.offset(), 77 | height = draggable.height(), 78 | width = draggable.width(); 79 | 80 | shadow_top.style.width = (offset.left + width) + 'px'; 81 | shadow_top.style.height = offset.top + 'px'; 82 | 83 | shadow_left.style.width = offset.left + 'px'; 84 | shadow_left.style.height = (document.height - offset.top) + 'px'; 85 | shadow_left.style.top = offset.top + 'px'; 86 | 87 | shadow_right.style.width = (document.width - offset.left - width) + 'px'; 88 | shadow_right.style.height = document.height + 'px'; 89 | shadow_right.style.left = (offset.left + width) + 'px'; 90 | 91 | shadow_bottom.style.width = width + 'px'; 92 | shadow_bottom.style.height = (document.height - offset.top - height) + 'px'; 93 | shadow_bottom.style.left = offset.left + 'px'; 94 | shadow_bottom.style.top = (offset.top + height) + 'px'; 95 | 96 | drag_t.style.left = (draggable.width()/2 - 3) + 'px'; 97 | drag_b.style.left = (draggable.width()/2 - 3) + 'px'; 98 | 99 | drag_r.style.top = (draggable.height()/2 - 3) + 'px'; 100 | drag_l.style.top = (draggable.height()/2 - 3) + 'px'; 101 | } 102 | 103 | updateShadow(); 104 | 105 | function updateSizes() { 106 | draggable.find('.size').html(draggable.width() + " X " + draggable.height()); 107 | } 108 | 109 | updateSizes(); 110 | 111 | var self = this; 112 | 113 | draggable.bind('mousedown', function(evt){ 114 | self.minus_draggable_area = $(evt.target); 115 | 116 | self.position = draggable.position(); 117 | self.position.right = self.position.left + draggable.width(); 118 | self.position.bottom = self.position.top + draggable.height(); 119 | 120 | self.start_x = evt.pageX; 121 | self.start_y = evt.pageY; 122 | }); 123 | 124 | $(window.document).bind('mousemove', function(evt){ 125 | if (self.minus_draggable_area) { 126 | var match = self.minus_draggable_area[0].className.match(/drag (\w+)/); 127 | 128 | if (match) { 129 | var area = self.minus_draggable_area.parent(); 130 | 131 | var diff_x = self.start_x - evt.pageX; 132 | var diff_y = self.start_y - evt.pageY; 133 | 134 | switch (match[1]) { 135 | case 'tl': 136 | area.css({ 137 | top: evt.pageY, 138 | left: evt.pageX, 139 | 140 | width: self.position.right - evt.pageX, 141 | height: self.position.bottom - evt.pageY 142 | }); 143 | 144 | break; 145 | 146 | case 'tr': 147 | area.css({ 148 | top: evt.pageY, 149 | 150 | width: evt.pageX - self.position.left, 151 | height: self.position.bottom - evt.pageY 152 | }); 153 | 154 | break; 155 | 156 | case 'bl': 157 | area.css({ 158 | left: evt.pageX, 159 | 160 | width: self.position.right - evt.pageX, 161 | height: evt.pageY - self.position.top 162 | }); 163 | 164 | break; 165 | 166 | case 'br': 167 | area.css({ 168 | width: evt.pageX - self.position.left, 169 | height: evt.pageY - self.position.top 170 | }); 171 | break; 172 | 173 | case 't': 174 | area.css({ 175 | top: evt.pageY, 176 | height: self.position.bottom - evt.pageY 177 | }); 178 | break; 179 | 180 | case 'l': 181 | area.css({ 182 | left: evt.pageX, 183 | width: self.position.right - evt.pageX, 184 | }); 185 | break; 186 | 187 | case 'r': 188 | area.css({ 189 | width: evt.pageX - self.position.left, 190 | }); 191 | break; 192 | 193 | case 'b': 194 | area.css({ 195 | height: evt.pageY - self.position.top 196 | }); 197 | break; 198 | } 199 | 200 | self.start_x = evt.pageX; 201 | self.start_y = evt.pageY; 202 | 203 | updateShadow(); 204 | updateSizes(); 205 | } else { 206 | var el = self.minus_draggable_area[0]; 207 | 208 | el.style.left = (el.offsetLeft - self.start_x + evt.pageX) + 'px'; 209 | el.style.top = (el.offsetTop - self.start_y + evt.pageY) + 'px'; 210 | 211 | self.start_x = evt.pageX; 212 | self.start_y = evt.pageY; 213 | 214 | updateShadow(); 215 | } 216 | } 217 | }); 218 | 219 | $(window.document).bind('mouseup', function(evt){ 220 | delete self.minus_draggable_area; 221 | }); 222 | 223 | draggable.find('.ok').bind('click', function(){ 224 | container.css({ visibility: "hidden" }); 225 | 226 | setTimeout(function(){ 227 | browser.postMessage({ 228 | method:'takeScreenshot', 229 | captureType:'region', 230 | finished: true, 231 | 232 | bounds: { 233 | top: draggable[0].offsetTop - document.body.scrollTop, 234 | left: draggable[0].offsetLeft - document.body.scrollLeft, 235 | width: draggable.width(), 236 | height: draggable.height() 237 | } 238 | }); 239 | 240 | container.remove(); 241 | }, 100); 242 | }); 243 | 244 | draggable.find('.cancel').bind('click', function(){ 245 | container.remove(); 246 | }); 247 | 248 | container.css({ visibility: "visible" }); 249 | } 250 | 251 | 252 | function resetScroll() { 253 | saved_scroll = document.body.scrollTop; 254 | scroll_position = 0; 255 | // scroll to top 256 | window.scrollTo(0,0); 257 | 258 | setTimeout(function(){ 259 | browser.postMessage({ method:"takeScreenshot", captureType:"scroll" }); 260 | }, 100); 261 | } 262 | 263 | function restoreScroll() { 264 | window.scrollTo(0, saved_scroll); 265 | } 266 | 267 | function scrollPage() { 268 | console.log('scrolling page'); 269 | 270 | var displayHeight = document.documentElement.clientHeight; 271 | 272 | // If end of the page 273 | if ((displayHeight + document.body.scrollTop) >= document.body.scrollHeight) { 274 | console.log('finished'); 275 | 276 | browser.postMessage({ method:"takeScreenshot", captureType:"scroll", finished: true }); 277 | 278 | restoreScroll(); 279 | } else { 280 | scroll_position = scroll_position + displayHeight; 281 | 282 | var old_scroll_top = document.body.scrollTop; 283 | 284 | window.scrollTo(0, scroll_position); 285 | 286 | (function(scroll){ 287 | setTimeout(function(){ 288 | browser.postMessage({ 289 | method:"takeScreenshot", 290 | captureType:"scroll", 291 | heightFix: (displayHeight - (document.body.scrollTop - scroll)) 292 | }); 293 | }, 100); 294 | })(old_scroll_top); 295 | } 296 | } 297 | 298 | var settings = {}; 299 | 300 | $(document).bind('keydown', function (event) { 301 | var isMac = browser.isPlatform('mac'); 302 | var keyCode = event.keyCode; 303 | 304 | // Send compose key like Ctrl + Alt + alphabetical-key to background. 305 | if ((event.ctrlKey && event.altKey && !isMac || 306 | event.metaKey && event.altKey && isMac) && 307 | keyCode > 64 && keyCode < 91) 308 | { 309 | var charcode = String.fromCharCode(keyCode).toUpperCase(); 310 | 311 | console.log(charcode, settings) 312 | 313 | if (settings[charcode]) { 314 | browser.postMessage({ method: 'takeScreenshot', captureType: settings[charcode] }); 315 | } 316 | } 317 | }); 318 | 319 | 320 | browser.addMessageListener(function(msg) { 321 | console.log('received message', msg); 322 | 323 | switch (msg.method) { 324 | case "scroll": 325 | if (msg.initial) { 326 | resetScroll(); 327 | } else { 328 | scrollPage(); 329 | } 330 | 331 | break; 332 | case "region": 333 | initializeDrag(); 334 | 335 | break; 336 | 337 | case "updateSettings": 338 | settings = msg.settings; 339 | break; 340 | 341 | default: 342 | break; 343 | } 344 | }); 345 | 346 | browser.onReady(function(){ 347 | browser.postMessage({ method: "updateSettings" }); 348 | }); 349 | 350 | } 351 | -------------------------------------------------------------------------------- /css/popup.css: -------------------------------------------------------------------------------- 1 | * { 2 | outline: 0 !important; 3 | } 4 | 5 | input { 6 | border: 1px solid #ccc; 7 | } 8 | 9 | a, a:visited { 10 | text-decoration: none; 11 | color:#555; 12 | } 13 | 14 | a:hover { 15 | text-decoration: underline; 16 | color: #2200C1; 17 | } 18 | 19 | body { 20 | width: 380px; 21 | height: auto; 22 | margin: 0; 23 | font-family: helvetica, arial; 24 | font-size: 14px; 25 | 26 | overflow: hidden; 27 | background: url(../images/popup_bg.png) repeat-x; 28 | } 29 | 30 | #signin { 31 | width: 542px; 32 | height: 330px !important; 33 | background: white; 34 | border: 0px solid #ddd; 35 | border-top: 1px solid rgba(0,0,0,0); 36 | border-bottom: 2px solid #ddd; 37 | border-radius: 3px; 38 | z-index: 9999999; 39 | background: url(../images/signup_bg.png); 40 | } 41 | 42 | #signin .error { 43 | color: red; 44 | text-align: center; 45 | font-weight: bold; 46 | font-size: 14px; 47 | height: 20px; 48 | } 49 | 50 | #signin .relative { 51 | margin-top: 0px; 52 | } 53 | 54 | #signin form { 55 | float: left; 56 | position: relative; 57 | width: 242px; 58 | height: 220px; 59 | padding-left: 28px; 60 | } 61 | 62 | #signin form h3 { 63 | font-size: 19px; 64 | font-family: helvetica, arial; 65 | font-weight: bold; 66 | color: #666; 67 | padding-bottom: 15px; 68 | } 69 | 70 | #signin form span { 71 | display: block; 72 | font-size: 13px; 73 | color: #666; 74 | opacity: 0.8; 75 | padding-bottom: 8px; 76 | padding-top: 10px; 77 | } 78 | 79 | #signin form label { 80 | display: block; 81 | font-size: 11px; 82 | color: #666; 83 | } 84 | 85 | #signin form label input { 86 | vertical-align: bottom; 87 | } 88 | 89 | #signin .logo { 90 | text-align: center; 91 | background: url(../images/popup_logo.png?1) center no-repeat; 92 | height: 44px; 93 | padding: 15px; 94 | } 95 | 96 | #signin form.error input { 97 | border: 1px solid red; 98 | } 99 | 100 | #signin form input[type=text], #signin form input[type=password] { 101 | width: 195px; 102 | border: 1px solid #ccc; 103 | padding: 12px; 104 | margin-bottom: 6px; 105 | } 106 | 107 | #signin form input[type=submit] { 108 | position: absolute; 109 | bottom: 0px; 110 | right: 20px; 111 | 112 | cursor: pointer; 113 | background: url(../images/button_bg.png); 114 | border: none; 115 | width: 102px; 116 | height: 32px; 117 | padding: 6px 8px; 118 | padding-top: 3px; 119 | text-align: center; 120 | font-weight: bold; 121 | color: #363636; 122 | font-size: 16px; 123 | } 124 | 125 | #signin .loader { 126 | display: none; 127 | position: absolute; 128 | left: 30px; 129 | top: 30px; 130 | } 131 | 132 | #signin.loading .loader { 133 | display: block; 134 | } 135 | 136 | #signin form input[type=submit]:hover { 137 | color: #f19600; 138 | } 139 | 140 | #signin .signin { 141 | background: url(../images/separator.png) center right no-repeat; 142 | } 143 | 144 | #header { 145 | padding-left: 10px; 146 | position: relative; 147 | z-index: 999999; 148 | margin-top: 10px; 149 | } 150 | 151 | #header .more { 152 | width: 62px; 153 | height: 47px; 154 | 155 | position: absolute; 156 | top: 0px; 157 | right: 10px; 158 | 159 | text-align: center; 160 | font-size: 20px; 161 | 162 | background: white; 163 | 164 | 165 | background-image: url(../images/gear.png), url(../images/take_screenshot.png); 166 | background-repeat: no-repeat, repeat-x; 167 | background-position: center, top center; 168 | } 169 | 170 | #header .more.hover { 171 | text-decoration: none; 172 | cursor: pointer; 173 | opacity: 1; 174 | 175 | z-index: 99999; 176 | 177 | background: white url(../images/gear.png) center 10px no-repeat; 178 | border: 2px solid #666; 179 | border-bottom: none; 180 | 181 | width: 58px; 182 | height: 47px; 183 | 184 | box-shadow: 0 0 3px 1px #ccc; 185 | } 186 | 187 | #header .more.hover img { 188 | opacity: 1; 189 | } 190 | 191 | #header .more > div { 192 | position: absolute; 193 | 194 | top: 45px; 195 | right: -2px; 196 | 197 | width: 225px; 198 | 199 | background: white; 200 | border: 2px solid #666; 201 | 202 | font-size: 16px; 203 | text-align: left; 204 | 205 | z-index: 9999; 206 | opacity: 1; 207 | 208 | box-shadow: 0 0 3px 1px #ccc; 209 | 210 | padding-top: 8px; 211 | } 212 | 213 | #header .connector { 214 | position: absolute; 215 | right: -2px; 216 | top: -5px; 217 | height: 5px; 218 | width: 58px; 219 | background: white; 220 | border-left: 2px solid #666; 221 | border-right: 2px solid #666; 222 | } 223 | 224 | #header .more > div li { 225 | padding: 8px 10px; 226 | color: #999; 227 | font-size: 13px; 228 | } 229 | 230 | #header .more > div li:hover span, #header .more > div li:hover label { 231 | color: #f7931e; 232 | text-decoration: underline; 233 | cursor: pointer; 234 | } 235 | 236 | #header .more > div span { 237 | float: right; 238 | font-size: 12px; 239 | color: #666; 240 | font-weight: bold; 241 | } 242 | 243 | #header .more .edit_image_config { 244 | margin-top: 10px; 245 | 246 | border-top: 1px solid #ccc; 247 | line-height: 12px; 248 | } 249 | 250 | #header .more .options { 251 | cursor: pointer; 252 | font-size: 14px; 253 | } 254 | 255 | #header .more .edit_image_config input { 256 | vertical-align: middle; 257 | } 258 | 259 | #header .more .edit_image_config label { 260 | cursor: pointer; 261 | margin-left: 5px; 262 | font-size: 11px; 263 | text-transform: uppercase; 264 | vertical-align: middle; 265 | } 266 | 267 | #timeline { 268 | background: url(../images/dashboard.png); 269 | margin: 0px 10px; 270 | height: 22px; 271 | width: 361px; 272 | text-transform: uppercase; 273 | 274 | font-size: 12px; 275 | 276 | color: #999; 277 | font-weight: bold; 278 | 279 | padding-top: 7px; 280 | 281 | cursor: default; 282 | 283 | font-weight: bold; 284 | } 285 | 286 | #timeline span { 287 | margin-right: 33px; 288 | margin-left: 15px; 289 | } 290 | 291 | #timeline a { 292 | color: #999; 293 | margin-right: 16px; 294 | cursor: pointer; 295 | } 296 | 297 | #timeline a.active { 298 | color: #333; 299 | } 300 | 301 | 302 | #latest_file input { 303 | width: 210px; 304 | margin-left: 5px; 305 | } 306 | 307 | #galleries_container { 308 | margin: 0; 309 | height: auto; 310 | max-height: 380px; 311 | width: 100%; 312 | overflow-x: hidden; 313 | 314 | margin-top: 10px; 315 | } 316 | 317 | #my_galleries { 318 | margin:0; 319 | padding:0; 320 | list-style: none; 321 | 322 | width: 100%; 323 | } 324 | 325 | #my_galleries li { 326 | padding: 8px; 327 | margin-top: 5px; 328 | margin-bottom: 10px; 329 | 330 | border: 1px solid #cecece; 331 | box-shadow: 0 0 3px 1px rgba(200,200,200, 0.3); 332 | 333 | position: relative; 334 | 335 | margin-left: 10px; 336 | margin-right: 10px; 337 | 338 | width: 324px; 339 | height: 60px; 340 | 341 | background: #fff; 342 | font-weight: bold; 343 | } 344 | 345 | #my_galleries li.loader { 346 | background: url(../images/loading.gif) center no-repeat; 347 | margin-left: 30px; 348 | height: 30px; 349 | box-shadow: none; 350 | border: none; 351 | } 352 | 353 | #my_galleries li .preview { 354 | padding-right: 10px; 355 | } 356 | 357 | #my_galleries li .action { 358 | position: relative; 359 | } 360 | 361 | #my_galleries li .action img { 362 | position: absolute; 363 | top: -9px; 364 | right: -9px; 365 | } 366 | 367 | #my_galleries li .action a { 368 | cursor: pointer; 369 | } 370 | 371 | #my_galleries li .action a:hover { 372 | } 373 | 374 | #my_galleries li .creator { 375 | font-size: 12px; 376 | color: #999; 377 | cursor: default; 378 | } 379 | 380 | #my_galleries li .creator a { 381 | color: #f19600; 382 | cursor: pointer; 383 | } 384 | 385 | #my_galleries .name { 386 | max-width: 215px; 387 | display: inline-block; 388 | overflow: hidden; 389 | white-space: nowrap; 390 | text-overflow: ellipsis; 391 | color: #333; 392 | font-size: 15px; 393 | } 394 | 395 | #my_galleries .share_link { 396 | background: #eee; 397 | width: 185px; 398 | } 399 | 400 | #my_galleries .items { 401 | margin-right: 0px; 402 | font-size: 12px; 403 | font-family: Arial; 404 | color: #999; 405 | white-space: nowrap; 406 | cursor: default; 407 | } 408 | 409 | #my_galleries .items.dot { 410 | display: inline-block; 411 | width: 6px; 412 | height: 16px; 413 | background: url(../images/don.png) no-repeat center; 414 | } 415 | 416 | #take_screenshot { 417 | display: block; 418 | width: 286px; 419 | 420 | cursor: pointer; 421 | 422 | font-size: 22px; 423 | font-weight: bold; 424 | 425 | color: #666; 426 | 427 | background-image: url(../images/btn_camera_gray.png), url(../images/take_screenshot.png); 428 | background-repeat: no-repeat, repeat-x; 429 | background-position: 15px 12px, top left; 430 | 431 | border: 0 !important; 432 | padding: 10px 15px; 433 | padding-left: 60px; 434 | 435 | padding-bottom: 10px; 436 | 437 | text-align: left; 438 | } 439 | 440 | #take_screenshot:hover { 441 | color: #333; 442 | 443 | background-image: url(../images/btn_camera_normal.png), url(../images/take_screenshot.png); 444 | } 445 | 446 | .loading #take_screenshot { 447 | text-indent: -99999px; 448 | background-image: url(../images/loading.gif), url(../images/take_screenshot.png); 449 | background-position: center, top center; 450 | } 451 | 452 | .loading .more { 453 | display: none; 454 | } 455 | 456 | h4 { 457 | margin: 0; 458 | padding: 0px 5px; 459 | } 460 | 461 | a.button { 462 | padding: 10px 14px; 463 | margin-right: 2px; 464 | border: 1px solid #ccc; 465 | border-radius: 2px; 466 | 467 | font-size: 20px; 468 | 469 | background: #fff; 470 | 471 | text-align: center; 472 | } 473 | 474 | a.button:hover { 475 | text-decoration: none; 476 | 477 | background: #eee; 478 | 479 | color: #333; 480 | } 481 | 482 | .center { 483 | text-align: center; 484 | } 485 | 486 | 487 | #footer { 488 | clear: both; 489 | height: 25px; 490 | margin-top: 5px; 491 | padding-top: 6px; 492 | padding-bottom: 9px; 493 | margin-left: 10px; 494 | 495 | position: relative; 496 | 497 | background: url(../images/bottom.png) top left no-repeat; 498 | } 499 | 500 | #footer * { 501 | float: left; 502 | } 503 | 504 | #footer img { 505 | vertical-align: middle; 506 | margin-left: 10px; 507 | } 508 | 509 | #footer a.minus_link { 510 | position: absolute; 511 | bottom: 9px; 512 | right: 60px; 513 | width: 80px; 514 | font-size: 13px; 515 | } 516 | 517 | #footer .options { 518 | font-size: 12px; 519 | font-weight: bold; 520 | color: #000; 521 | opacity: 0.7; 522 | margin-left: 10px; 523 | } 524 | 525 | #user { 526 | font-size: 11px; 527 | font-weight: bold; 528 | color: #999; 529 | margin-right: 0px; 530 | float: right; 531 | padding-top: 3px; 532 | 533 | text-transform: uppercase; 534 | } 535 | 536 | #user { 537 | text-align: left; 538 | } 539 | 540 | #user:hover { 541 | color: #333; 542 | text-decoration: none; 543 | } 544 | 545 | #signout { 546 | float: right; 547 | font-size: 12px; 548 | font-weight: normal; 549 | opacity: 0.5; 550 | padding-top: 4px; 551 | margin-right: 18px; 552 | } 553 | 554 | #signout:hover { 555 | opacity: 1; 556 | } 557 | 558 | #loader { 559 | position: absolute; 560 | top: 0px; 561 | left: 0px; 562 | height: 100%; 563 | width: 100%; 564 | background: rgba(200,200,200, 0.4); 565 | font-size: 16px; 566 | font-family: verdana, sans-serif; 567 | } 568 | 569 | #loader div { 570 | margin-top: 25%; 571 | background: url(../images/ajax-loader.gif) bottom center no-repeat; 572 | margin-left: auto; 573 | margin-right: auto; 574 | 575 | width: 200px; 576 | height: 20px; 577 | text-align: center; 578 | } 579 | 580 | /************* Scrollbar ***************/ 581 | .jspVerticalBar 582 | { 583 | right: 6px; 584 | border-radius: 3px; 585 | background-color: #cbcbcd; 586 | } 587 | 588 | .jspDrag { 589 | background: url(../images/scroll.png) no-repeat; 590 | width: 15px; 591 | height: 87px; 592 | 593 | left: -3px; 594 | } 595 | 596 | /********** Opera css ***********/ 597 | 598 | .opera #take_screenshot { 599 | display: none; 600 | } 601 | 602 | .opera #header span { 603 | display: none; 604 | } 605 | 606 | .opera #header:after { 607 | content: ""; 608 | } 609 | 610 | 611 | /********** Firefox css *********/ 612 | .firefox #main_content { 613 | padding-bottom: 10px; 614 | } 615 | 616 | .firefox #header li[data-screenshot-type='region'] { 617 | display: none; 618 | } -------------------------------------------------------------------------------- /js/popup.js: -------------------------------------------------------------------------------- 1 | (function(){ 2 | function reinitializePane() { 3 | var pane = $("#galleries_container").data('jsp'); 4 | if (pane) 5 | pane.reinitialise(); 6 | } 7 | 8 | var current_page = 1; 9 | var total_pages; 10 | var timeline_type = window.store.get('timeline_type') || 'mine'; 11 | 12 | $('#timeline a').live('click', function(){ 13 | current_page = 1; 14 | timeline_type = $(this).data('timeline'); 15 | window.store.set('timeline_type', timeline_type); 16 | 17 | updateTimeline(); 18 | }); 19 | 20 | function updateTimeline(skip_loader) { 21 | $('#timeline a.active').removeClass('active'); 22 | $('#timeline a[data-timeline='+timeline_type+']').addClass('active'); 23 | 24 | if (!skip_loader) 25 | $('#my_galleries').html("
  • "); 26 | 27 | reinitializePane(); 28 | 29 | updateGalleries(); 30 | } 31 | 32 | var ICON_ARCHIVE = "../images/generic_file.png"; 33 | 34 | function updateGalleries() { 35 | Minus.timeline(window.store.get('username'), timeline_type, current_page, function(resp) { 36 | total_pages = resp.pages; 37 | 38 | $("#my_galleries .loader").remove(); 39 | 40 | var html = $('#galleries_template').tmpl({ galleries: resp.results }); 41 | 42 | if (current_page == 1) { 43 | $('#my_galleries').html(html); 44 | } else { 45 | $('#my_galleries').append(html); 46 | } 47 | 48 | $('#my_galleries').find('.items.date').timeago() 49 | 50 | var loaded_images = 0; 51 | var imageLoaded = function() { 52 | loaded_images += 1; 53 | 54 | if (loaded_images == resp.results.length) { 55 | if (current_page == 1) { 56 | window.store.set('last_view', $('#my_galleries').html()); 57 | } 58 | 59 | reinitializePane() 60 | } 61 | } 62 | 63 | $('#my_galleries .preview img').each(function(){ 64 | var img = this; 65 | 66 | var img_preloader = new Image; 67 | var image = $(img).data('image'); 68 | 69 | if (!image) 70 | return img_preloader.src = ICON_ARCHIVE; 71 | 72 | img_url = $(img).data('image'); 73 | 74 | if (img_url.match(/^\/\//)) 75 | img_url = "http:" + img_url; 76 | 77 | img_preloader.src = img_url; 78 | 79 | img_preloader.onload = function(){ 80 | if (img_preloader.naturalHeight == 0) { 81 | img.src = ICON_ARCHIVE; 82 | } else { 83 | img.src = img_preloader.src; 84 | } 85 | 86 | imageLoaded(); 87 | } 88 | 89 | img_preloader.onerror = function(){ 90 | img.src = ICON_ARCHIVE; 91 | 92 | imageLoaded(); 93 | } 94 | }); 95 | 96 | var pane = $("#galleries_container").data('jsp'); 97 | 98 | if (pane) { 99 | pane.reinitialise(); 100 | } else { 101 | $("#galleries_container") 102 | .jScrollPane({ 103 | maintainPosition: true, 104 | verticalDragMinHeight: 87, 105 | verticalDragMaxHeight: 87 106 | }); 107 | } 108 | 109 | $("#galleries_container") 110 | .unbind('jsp-scroll-y') 111 | .bind( 112 | 'jsp-scroll-y', 113 | function(event, scrollPositionX, isAtLeft, isAtRight) { 114 | // Load next page 115 | if (isAtRight) { 116 | if (current_page < total_pages) { 117 | current_page += 1; 118 | 119 | $('#my_galleries').append("
  • "); 120 | 121 | updateGalleries(current_page); 122 | } 123 | 124 | reinitializePane(); 125 | } 126 | } 127 | ); 128 | 129 | }); 130 | } 131 | 132 | browser.addMessageListener(function(msg, sender) { 133 | $('#header').removeClass('loading'); 134 | 135 | if (msg.method == "screenshotComplete") { 136 | updateTimeline(); 137 | } else { 138 | //updateUser(); 139 | } 140 | }); 141 | 142 | $('#take_screenshot').live('click', function(){ 143 | var parent = $(this).parent(); 144 | 145 | if (!parent.hasClass('loading')) { 146 | var screenshot_type = parent.find('li').data('screenshot-type'); 147 | 148 | if (screenshot_type) { 149 | parent.addClass('loading'); 150 | 151 | browser.postMessage({ method: 'takeScreenshot', captureType: screenshot_type }); 152 | 153 | if (screenshot_type == 'region') { 154 | setTimeout(window.close, 100); 155 | } 156 | } 157 | } 158 | }); 159 | 160 | $('#header .more li[data-screenshot-type]').live('click', function(){ 161 | if (!$('#header').hasClass('loading')) { 162 | $('#header').addClass('loading'); 163 | 164 | browser.postMessage({ method: 'takeScreenshot', captureType: $(this).data('screenshot-type') }); 165 | 166 | if ($(this).data('screenshot-type') == 'region') 167 | setTimeout(window.close, 100); 168 | } 169 | }); 170 | 171 | $('#header .more').hover( 172 | function(){ 173 | clearInterval(this.timer); 174 | $(this).addClass('hover') 175 | .find('div').show(); 176 | }, 177 | function(){ 178 | var self = $(this); 179 | 180 | this.timer = setTimeout(function(){ 181 | self.removeClass('hover') 182 | .find('div').hide(); 183 | }, 500); 184 | } 185 | ); 186 | 187 | function authUser() { 188 | var $form = $('#signin form.signin'); 189 | var form_data = $form.serializeArray(); 190 | 191 | $("#signin").addClass('loading'); 192 | 193 | Minus.oauthToken(form_data[0].value, form_data[1].value, 194 | function(resp) { 195 | $("#signin").removeClass('loading'); 196 | 197 | if (resp.error) { 198 | $('#signin .error').html('Wrong user/password combination.'); 199 | } else { 200 | window.store.set('username', form_data[0].value); 201 | 202 | console.log(form_data); 203 | 204 | if (form_data[2]) { 205 | window.store.set('access_token', resp.access_token); 206 | window.store.set('refresh_token', resp.refresh_token); 207 | } else { 208 | window.store.remove('access_token'); 209 | window.store.remove('refresh_token'); 210 | } 211 | 212 | updateUser(); 213 | 214 | $('#signin').hide(); 215 | $('#main_content').show(); 216 | 217 | $('body').css({ 'width': '380px' }); 218 | browser.resizePopup(); 219 | } 220 | } 221 | ); 222 | 223 | return false; 224 | } 225 | 226 | $('#signin form.signin').bind('submit', authUser); 227 | 228 | function registerUser() { 229 | var $form = $('#signin form.signup'); 230 | var form_data = $form.serializeArray(); 231 | 232 | $("#signin").addClass('loading'); 233 | 234 | Minus.registerUser(form_data[0].value, form_data[1].value, form_data[2].value, 235 | function(resp) { 236 | $("#signin").removeClass('loading'); 237 | 238 | if (!resp.success) { 239 | $('#signin .error').html(resp.username); 240 | } else { 241 | $signin_form = $('#signin form.signin'); 242 | 243 | $signin_form.find('input[name=username]').val(form_data[0].value); 244 | $signin_form.find('input[name=password]').val(form_data[1].value); 245 | 246 | authUser(); 247 | } 248 | } 249 | ); 250 | 251 | return false; 252 | } 253 | 254 | 255 | $('#signin form.signup').bind('submit', registerUser); 256 | 257 | function updateUser() { 258 | console.log('user store:', window.store.get('username')); 259 | 260 | var user = window.store.get('username'); 261 | var token = window.store.get('access_token'); 262 | var skip_loader = window.store.get('last_view'); 263 | 264 | if (token && user) { 265 | Minus.setToken(token); 266 | 267 | Minus.activeUser(function(resp) { 268 | if (resp.invalid_token) { 269 | 270 | Minus.refreshToken(window.store.get('refresh_token'), 271 | function(refresh_resp) { 272 | if (refresh_resp.error) { 273 | $('body').css({ 'width': '542px' }); 274 | browser.resizePopup(); 275 | 276 | $('#main_content').hide(); 277 | $('#signin').show(); 278 | } else { 279 | console.log(refresh_resp); 280 | 281 | window.store.set('access_token', refresh_resp.access_token); 282 | window.store.set('refresh_token', refresh_resp.refresh_token); 283 | 284 | updateTimeline(skip_loader); 285 | } 286 | } 287 | ); 288 | } else { 289 | updateTimeline(skip_loader); 290 | } 291 | }); 292 | 293 | $('#user').attr('href','http://minus.com/' + user); 294 | } else { 295 | $('body').css({ 'width': '542px' }); 296 | browser.resizePopup(); 297 | 298 | $('#main_content').hide(); 299 | $('#signin').show(); 300 | } 301 | } 302 | 303 | function updateUI() { 304 | if (window.store.get('last_view')) { 305 | $('#my_galleries').html(window.store.get('last_view')); 306 | $("#galleries_container") 307 | .jScrollPane({ 308 | maintainPosition: true, 309 | verticalDragMinHeight: 87, 310 | verticalDragMaxHeight: 87 311 | }); 312 | 313 | } 314 | 315 | updateUser(); 316 | 317 | if (window.store.get('edit_image') == undefined) 318 | window.store.set('edit_image', true); 319 | 320 | $('#edit_image').attr('checked', window.store.get('edit_image')) 321 | 322 | $('#edit_image').bind('change', function(){ 323 | window.store.set('edit_image', this.checked); 324 | }); 325 | 326 | $('#header *[data-screenshot-type]').each(function(){ 327 | var hotkey = store.get('hotkey_'+$(this).data('screenshot-type')); 328 | 329 | if (hotkey) hotkey = (browser.isPlatform('mac') ? 'Cmd' : 'Ctrl') + "+Alt+" + hotkey; 330 | 331 | $(this).find('span').html(hotkey); 332 | }); 333 | 334 | $('#signout').bind('click', function(){ 335 | window.store.remove('username'); 336 | window.store.remove('access_token'); 337 | 338 | 339 | $('#main_content').hide(); 340 | $('#signin .error').html(''); 341 | $('#signin').show(); 342 | 343 | $('body').css({ 'width': '542px' }); 344 | browser.resizePopup(); 345 | }); 346 | 347 | browser.tabs.getSelected(null, function(tab) { 348 | if (browser.isFirefox) 349 | return true; 350 | 351 | if (tab.url.match('https://') || tab.url.match('chrome://') || tab.url.match("file://")) { 352 | $('#header *[data-screenshot-type=full], #header *[data-screenshot-type=region]').remove(); 353 | } 354 | 355 | if (tab.url.match('chrome://newtab') || tab.url.match('chrome://extensions')) { 356 | $('#header *[data-screenshot-type]').remove(); 357 | $('#take_screenshot').html('Not available for this page') 358 | .parent().find('.more').hide(); 359 | } 360 | }); 361 | } 362 | 363 | 364 | browser.onReady(function() { 365 | updateUI(); 366 | }); 367 | 368 | }()) 369 | -------------------------------------------------------------------------------- /css/chosen.css: -------------------------------------------------------------------------------- 1 | /* @group Base */ 2 | select.chzn-select { 3 | visibility: hidden; 4 | height: 28px !important; 5 | min-height: 28px !important; 6 | } 7 | .chzn-container { 8 | font-size: 13px; 9 | position: relative; 10 | display: inline-block; 11 | zoom: 1; 12 | *display: inline; 13 | } 14 | .chzn-container .chzn-drop { 15 | background: #fff; 16 | border: 1px solid #aaa; 17 | border-top: 0; 18 | position: absolute; 19 | top: 29px; 20 | left: 0; 21 | -webkit-box-shadow: 0 4px 5px rgba(0,0,0,.15); 22 | -moz-box-shadow : 0 4px 5px rgba(0,0,0,.15); 23 | -o-box-shadow : 0 4px 5px rgba(0,0,0,.15); 24 | box-shadow : 0 4px 5px rgba(0,0,0,.15); 25 | z-index: 999; 26 | } 27 | /* @end */ 28 | 29 | /* @group Single Chosen */ 30 | .chzn-container-single .chzn-single { 31 | background-color: #fff; 32 | background-image: -webkit-gradient(linear, left bottom, left top, color-stop(0, #eeeeee), color-stop(0.5, white)); 33 | background-image: -webkit-linear-gradient(center bottom, #eeeeee 0%, white 50%); 34 | background-image: -moz-linear-gradient(center bottom, #eeeeee 0%, white 50%); 35 | background-image: -o-linear-gradient(top, #eeeeee 0%,#ffffff 50%); 36 | background-image: -ms-linear-gradient(top, #eeeeee 0%,#ffffff 50%); 37 | filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#eeeeee', endColorstr='#ffffff',GradientType=0 ); 38 | background-image: linear-gradient(top, #eeeeee 0%,#ffffff 50%); 39 | -webkit-border-radius: 4px; 40 | -moz-border-radius : 4px; 41 | border-radius : 4px; 42 | -moz-background-clip : padding; 43 | -webkit-background-clip: padding-box; 44 | background-clip : padding-box; 45 | border: 1px solid #aaa; 46 | display: block; 47 | overflow: hidden; 48 | white-space: nowrap; 49 | position: relative; 50 | height: 26px; 51 | line-height: 26px; 52 | padding: 0 0 0 8px; 53 | color: #444; 54 | text-decoration: none; 55 | } 56 | .chzn-container-single .chzn-single span { 57 | margin-right: 26px; 58 | display: block; 59 | overflow: hidden; 60 | white-space: nowrap; 61 | -o-text-overflow: ellipsis; 62 | -ms-text-overflow: ellipsis; 63 | text-overflow: ellipsis; 64 | } 65 | .chzn-container-single .chzn-single div { 66 | -webkit-border-radius: 0 4px 4px 0; 67 | -moz-border-radius : 0 4px 4px 0; 68 | border-radius : 0 4px 4px 0; 69 | -moz-background-clip : padding; 70 | -webkit-background-clip: padding-box; 71 | background-clip : padding-box; 72 | background: #ccc; 73 | background-image: -webkit-gradient(linear, left bottom, left top, color-stop(0, #ccc), color-stop(0.6, #eee)); 74 | background-image: -webkit-linear-gradient(center bottom, #ccc 0%, #eee 60%); 75 | background-image: -moz-linear-gradient(center bottom, #ccc 0%, #eee 60%); 76 | background-image: -o-linear-gradient(bottom, #ccc 0%, #eee 60%); 77 | background-image: -ms-linear-gradient(top, #cccccc 0%,#eeeeee 60%); 78 | filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#cccccc', endColorstr='#eeeeee',GradientType=0 ); 79 | background-image: linear-gradient(top, #cccccc 0%,#eeeeee 60%); 80 | border-left: 1px solid #aaa; 81 | position: absolute; 82 | right: 0; 83 | top: 0; 84 | display: block; 85 | height: 100%; 86 | width: 18px; 87 | } 88 | .chzn-container-single .chzn-single div b { 89 | background: url('chosen-sprite.png') no-repeat 0 1px; 90 | display: block; 91 | width: 100%; 92 | height: 100%; 93 | } 94 | .chzn-container-single .chzn-search { 95 | padding: 3px 4px; 96 | margin: 0; 97 | white-space: nowrap; 98 | } 99 | .chzn-container-single .chzn-search input { 100 | background: #fff url('chosen-sprite.png') no-repeat 100% -20px; 101 | background: url('chosen-sprite.png') no-repeat 100% -20px, -webkit-gradient(linear, left bottom, left top, color-stop(0.85, white), color-stop(0.99, #eeeeee)); 102 | background: url('chosen-sprite.png') no-repeat 100% -20px, -webkit-linear-gradient(center bottom, white 85%, #eeeeee 99%); 103 | background: url('chosen-sprite.png') no-repeat 100% -20px, -moz-linear-gradient(center bottom, white 85%, #eeeeee 99%); 104 | background: url('chosen-sprite.png') no-repeat 100% -20px, -o-linear-gradient(bottom, white 85%, #eeeeee 99%); 105 | background: url('chosen-sprite.png') no-repeat 100% -20px, -ms-linear-gradient(top, #ffffff 85%,#eeeeee 99%); 106 | background: url('chosen-sprite.png') no-repeat 100% -20px, -ms-linear-gradient(top, #ffffff 85%,#eeeeee 99%); 107 | background: url('chosen-sprite.png') no-repeat 100% -20px, linear-gradient(top, #ffffff 85%,#eeeeee 99%); 108 | margin: 1px 0; 109 | padding: 4px 20px 4px 5px; 110 | outline: 0; 111 | border: 1px solid #aaa; 112 | font-family: sans-serif; 113 | font-size: 1em; 114 | } 115 | .chzn-container-single .chzn-drop { 116 | -webkit-border-radius: 0 0 4px 4px; 117 | -moz-border-radius : 0 0 4px 4px; 118 | border-radius : 0 0 4px 4px; 119 | -moz-background-clip : padding; 120 | -webkit-background-clip: padding-box; 121 | background-clip : padding-box; 122 | } 123 | /* @end */ 124 | 125 | /* @group Multi Chosen */ 126 | .chzn-container-multi .chzn-choices { 127 | background-color: #fff; 128 | background-image: -webkit-gradient(linear, left bottom, left top, color-stop(0.85, white), color-stop(0.99, #eeeeee)); 129 | background-image: -webkit-linear-gradient(center bottom, white 85%, #eeeeee 99%); 130 | background-image: -moz-linear-gradient(center bottom, white 85%, #eeeeee 99%); 131 | background-image: -o-linear-gradient(bottom, white 85%, #eeeeee 99%); 132 | background-image: -ms-linear-gradient(top, #ffffff 85%,#eeeeee 99%); 133 | filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#ffffff', endColorstr='#eeeeee',GradientType=0 ); 134 | background-image: linear-gradient(top, #ffffff 85%,#eeeeee 99%); 135 | border: 1px solid #aaa; 136 | margin: 0; 137 | padding: 0; 138 | cursor: text; 139 | overflow: hidden; 140 | height: auto !important; 141 | height: 1%; 142 | position: relative; 143 | } 144 | .chzn-container-multi .chzn-choices li { 145 | float: left; 146 | list-style: none; 147 | } 148 | .chzn-container-multi .chzn-choices .search-field { 149 | white-space: nowrap; 150 | margin: 0; 151 | padding: 0; 152 | } 153 | .chzn-container-multi .chzn-choices .search-field input { 154 | color: #666; 155 | background: transparent !important; 156 | border: 0 !important; 157 | padding: 5px; 158 | margin: 1px 0; 159 | outline: 0; 160 | -webkit-box-shadow: none; 161 | -moz-box-shadow : none; 162 | -o-box-shadow : none; 163 | box-shadow : none; 164 | } 165 | .chzn-container-multi .chzn-choices .search-field .default { 166 | color: #999; 167 | } 168 | .chzn-container-multi .chzn-choices .search-choice { 169 | -webkit-border-radius: 3px; 170 | -moz-border-radius : 3px; 171 | border-radius : 3px; 172 | -moz-background-clip : padding; 173 | -webkit-background-clip: padding-box; 174 | background-clip : padding-box; 175 | background-color: #e4e4e4; 176 | background-image: -webkit-gradient(linear, left bottom, left top, color-stop(0, #e4e4e4), color-stop(0.7, #eeeeee)); 177 | background-image: -webkit-linear-gradient(center bottom, #e4e4e4 0%, #eeeeee 70%); 178 | background-image: -moz-linear-gradient(center bottom, #e4e4e4 0%, #eeeeee 70%); 179 | background-image: -o-linear-gradient(bottom, #e4e4e4 0%, #eeeeee 70%); 180 | background-image: -ms-linear-gradient(top, #e4e4e4 0%,#eeeeee 70%); 181 | filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#e4e4e4', endColorstr='#eeeeee',GradientType=0 ); 182 | background-image: linear-gradient(top, #e4e4e4 0%,#eeeeee 70%); 183 | color: #333; 184 | border: 1px solid #b4b4b4; 185 | line-height: 13px; 186 | padding: 3px 19px 3px 6px; 187 | margin: 3px 0 3px 5px; 188 | position: relative; 189 | } 190 | .chzn-container-multi .chzn-choices .search-choice span { 191 | cursor: default; 192 | } 193 | .chzn-container-multi .chzn-choices .search-choice-focus { 194 | background: #d4d4d4; 195 | } 196 | .chzn-container-multi .chzn-choices .search-choice .search-choice-close { 197 | display: block; 198 | position: absolute; 199 | right: 5px; 200 | top: 6px; 201 | width: 8px; 202 | height: 9px; 203 | font-size: 1px; 204 | background: url(chosen-sprite.png) right top no-repeat; 205 | } 206 | .chzn-container-multi .chzn-choices .search-choice .search-choice-close:hover { 207 | background-position: right -9px; 208 | } 209 | .chzn-container-multi .chzn-choices .search-choice-focus .search-choice-close { 210 | background-position: right -9px; 211 | } 212 | /* @end */ 213 | 214 | /* @group Results */ 215 | .chzn-container .chzn-results { 216 | margin: 0 4px 4px 0; 217 | max-height: 190px; 218 | padding: 0 0 0 4px; 219 | position: relative; 220 | overflow-x: hidden; 221 | overflow-y: auto; 222 | } 223 | .chzn-container-multi .chzn-results { 224 | margin: -1px 0 0; 225 | padding: 0; 226 | } 227 | .chzn-container .chzn-results li { 228 | line-height: 80%; 229 | padding: 7px 7px 8px; 230 | margin: 0; 231 | list-style: none; 232 | } 233 | .chzn-container .chzn-results .active-result { 234 | cursor: pointer; 235 | } 236 | .chzn-container .chzn-results .highlighted { 237 | background: #3875d7; 238 | color: #fff; 239 | } 240 | .chzn-container .chzn-results li em { 241 | background: #feffde; 242 | font-style: normal; 243 | } 244 | .chzn-container .chzn-results .highlighted em { 245 | background: transparent; 246 | } 247 | .chzn-container .chzn-results .no-results { 248 | background: #f4f4f4; 249 | } 250 | .chzn-container .chzn-results .group-result { 251 | cursor: default; 252 | color: #999; 253 | font-weight: bold; 254 | } 255 | .chzn-container .chzn-results .group-option { 256 | padding-left: 20px; 257 | } 258 | .chzn-container-multi .chzn-drop .result-selected { 259 | display: none; 260 | } 261 | /* @end */ 262 | 263 | /* @group Active */ 264 | .chzn-container-active .chzn-single { 265 | -webkit-box-shadow: 0 0 5px rgba(0,0,0,.3); 266 | -moz-box-shadow : 0 0 5px rgba(0,0,0,.3); 267 | -o-box-shadow : 0 0 5px rgba(0,0,0,.3); 268 | box-shadow : 0 0 5px rgba(0,0,0,.3); 269 | border: 1px solid #5897fb; 270 | } 271 | .chzn-container-active .chzn-single-with-drop { 272 | border: 1px solid #aaa; 273 | -webkit-box-shadow: 0 1px 0 #fff inset; 274 | -moz-box-shadow : 0 1px 0 #fff inset; 275 | -o-box-shadow : 0 1px 0 #fff inset; 276 | box-shadow : 0 1px 0 #fff inset; 277 | background-color: #eee; 278 | background-image: -webkit-gradient(linear, left bottom, left top, color-stop(0, white), color-stop(0.5, #eeeeee)); 279 | background-image: -webkit-linear-gradient(center bottom, white 0%, #eeeeee 50%); 280 | background-image: -moz-linear-gradient(center bottom, white 0%, #eeeeee 50%); 281 | background-image: -o-linear-gradient(bottom, white 0%, #eeeeee 50%); 282 | background-image: -ms-linear-gradient(top, #ffffff 0%,#eeeeee 50%); 283 | filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#ffffff', endColorstr='#eeeeee',GradientType=0 ); 284 | background-image: linear-gradient(top, #ffffff 0%,#eeeeee 50%); 285 | -webkit-border-bottom-left-radius : 0; 286 | -webkit-border-bottom-right-radius: 0; 287 | -moz-border-radius-bottomleft : 0; 288 | -moz-border-radius-bottomright: 0; 289 | border-bottom-left-radius : 0; 290 | border-bottom-right-radius: 0; 291 | } 292 | .chzn-container-active .chzn-single-with-drop div { 293 | background: transparent; 294 | border-left: none; 295 | } 296 | .chzn-container-active .chzn-single-with-drop div b { 297 | background-position: -18px 1px; 298 | } 299 | .chzn-container-active .chzn-choices { 300 | -webkit-box-shadow: 0 0 5px rgba(0,0,0,.3); 301 | -moz-box-shadow : 0 0 5px rgba(0,0,0,.3); 302 | -o-box-shadow : 0 0 5px rgba(0,0,0,.3); 303 | box-shadow : 0 0 5px rgba(0,0,0,.3); 304 | border: 1px solid #5897fb; 305 | } 306 | .chzn-container-active .chzn-choices .search-field input { 307 | color: #111 !important; 308 | } 309 | /* @end */ 310 | 311 | /* @group Right to Left */ 312 | .chzn-rtl { direction:rtl;text-align: right; } 313 | .chzn-rtl .chzn-single { padding-left: 0; padding-right: 8px; } 314 | .chzn-rtl .chzn-single span { margin-left: 26px; margin-right: 0; } 315 | .chzn-rtl .chzn-single div { 316 | left: 0; right: auto; 317 | border-left: none; border-right: 1px solid #aaaaaa; 318 | -webkit-border-radius: 4px 0 0 4px; 319 | -moz-border-radius : 4px 0 0 4px; 320 | border-radius : 4px 0 0 4px; 321 | } 322 | .chzn-rtl .chzn-choices li { float: right; } 323 | .chzn-rtl .chzn-choices .search-choice { padding: 3px 6px 3px 19px; margin: 3px 5px 3px 0; } 324 | .chzn-rtl .chzn-choices .search-choice .search-choice-close { left: 5px; right: auto; background-position: right top;} 325 | .chzn-rtl.chzn-container-single .chzn-results { margin-left: 4px; margin-right: 0; padding-left: 0; padding-right: 4px; } 326 | .chzn-rtl .chzn-results .group-option { padding-left: 0; padding-right: 20px; } 327 | .chzn-rtl.chzn-container-active .chzn-single-with-drop div { border-right: none; } 328 | .chzn-rtl .chzn-search input { 329 | background: url('chosen-sprite.png') no-repeat -38px -20px, #ffffff; 330 | background: url('chosen-sprite.png') no-repeat -38px -20px, -webkit-gradient(linear, left bottom, left top, color-stop(0.85, white), color-stop(0.99, #eeeeee)); 331 | background: url('chosen-sprite.png') no-repeat -38px -20px, -webkit-linear-gradient(center bottom, white 85%, #eeeeee 99%); 332 | background: url('chosen-sprite.png') no-repeat -38px -20px, -moz-linear-gradient(center bottom, white 85%, #eeeeee 99%); 333 | background: url('chosen-sprite.png') no-repeat -38px -20px, -o-linear-gradient(bottom, white 85%, #eeeeee 99%); 334 | background: url('chosen-sprite.png') no-repeat -38px -20px, -ms-linear-gradient(top, #ffffff 85%,#eeeeee 99%); 335 | background: url('chosen-sprite.png') no-repeat -38px -20px, -ms-linear-gradient(top, #ffffff 85%,#eeeeee 99%); 336 | background: url('chosen-sprite.png') no-repeat -38px -20px, linear-gradient(top, #ffffff 85%,#eeeeee 99%); 337 | padding: 4px 5px 4px 20px; 338 | } 339 | /* @end */ -------------------------------------------------------------------------------- /js/minus.js: -------------------------------------------------------------------------------- 1 | (function(window, undefined) { 2 | var API_KEY = 'fcebde22e53231ef95aa7238ef8dad'; 3 | var API_SECRET = 'b7b508ce60e4026292de30afd7cdce'; 4 | var API_TOKEN, API_USER; 5 | 6 | var emptyFunc = function(){}; 7 | 8 | function clone(obj){ 9 | if(obj == null || typeof(obj) != 'object') 10 | return obj; 11 | 12 | var temp = obj.constructor(); // changed 13 | 14 | for(var key in obj) 15 | temp[key] = clone(obj[key]); 16 | 17 | return temp; 18 | } 19 | 20 | function hashToQueryString(hash) { 21 | var params = []; 22 | 23 | for (key in hash) { 24 | if (hash.hasOwnProperty(key)) { 25 | params.push(key + "=" + hash[key]); 26 | } 27 | } 28 | 29 | return params.join('&'); 30 | } 31 | 32 | if (XMLHttpRequest && !XMLHttpRequest.prototype.sendAsBinary) { 33 | XMLHttpRequest.prototype.sendAsBinary = function(datastr) { 34 | if (window.chrome) { 35 | if (window.BlobBuilder) { 36 | var bb = new BlobBuilder(); 37 | } else { 38 | var bb = new window.WebKitBlobBuilder(); 39 | } 40 | 41 | var data = new ArrayBuffer(datastr.length); 42 | var ui8a = new Uint8Array(data, 0); 43 | for (var i=0; i 2 | 3 | 4 | 5 | 6 | 7 | 8 | 198 | 199 | 200 |
    201 |
    202 |
    203 | 204 | 205 | 221 | 222 | Loading editor... 223 |
    224 |
    225 |
    226 |
    227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 357 | 358 | 425 | 426 | 427 | 439 | 440 | 441 | -------------------------------------------------------------------------------- /js/chosen.jquery.min.js: -------------------------------------------------------------------------------- 1 | // Chosen, a Select Box Enhancer for jQuery and Protoype 2 | // by Patrick Filler for Harvest, http://getharvest.com 3 | // 4 | // Version 0.9.3 5 | // Full source at https://github.com/harvesthq/chosen 6 | // Copyright (c) 2011 Harvest http://getharvest.com 7 | 8 | // MIT License, https://github.com/harvesthq/chosen/blob/master/LICENSE.md 9 | // This file is generated by `cake build`, do not edit it by hand. 10 | (function(){var a,b,c,d,e=function(a,b){return function(){return a.apply(b,arguments)}};d=this,a=jQuery,a.fn.extend({chosen:function(c){return a.browser!=="msie"||a.browser.version!=="6.0"&&a.browser.version!=="7.0"?a(this).each(function(d){if(!a(this).hasClass("chzn-done"))return new b(this,c)}):this}}),b=function(){function b(b,c){this.form_field=b,this.options=c!=null?c:{},this.set_default_values(),this.form_field_jq=a(this.form_field),this.is_multiple=this.form_field.multiple,this.is_rtl=this.form_field_jq.hasClass("chzn-rtl"),this.default_text_default=this.form_field.multiple?"Select Some Options":"Select an Option",this.set_up_html(),this.register_observers(),this.form_field_jq.addClass("chzn-done")}b.prototype.set_default_values=function(){this.click_test_action=e(function(a){return this.test_active_click(a)},this),this.activate_action=e(function(a){return this.activate_field(a)},this),this.active_field=!1,this.mouse_on_container=!1,this.results_showing=!1,this.result_highlighted=null,this.result_single_selected=null,this.choices=0;return this.results_none_found=this.options.no_results_text||"No results match"},b.prototype.set_up_html=function(){var b,d,e,f;this.container_id=this.form_field.id.length?this.form_field.id.replace(/(:|\.)/g,"_"):this.generate_field_id(),this.container_id+="_chzn",this.f_width=this.form_field_jq.outerWidth(),this.default_text=this.form_field_jq.data("placeholder")?this.form_field_jq.data("placeholder"):this.default_text_default,b=a("
    ",{id:this.container_id,"class":"chzn-container"+(this.is_rtl?" chzn-rtl":""),style:"width: "+this.f_width+"px;"}),this.is_multiple?b.html('
      '):b.html(''+this.default_text+'
        '),this.form_field_jq.hide().after(b),this.container=a("#"+this.container_id),this.container.addClass("chzn-container-"+(this.is_multiple?"multi":"single")),this.dropdown=this.container.find("div.chzn-drop").first(),d=this.container.height(),e=this.f_width-c(this.dropdown),this.dropdown.css({width:e+"px",top:d+"px"}),this.search_field=this.container.find("input").first(),this.search_results=this.container.find("ul.chzn-results").first(),this.search_field_scale(),this.search_no_results=this.container.find("li.no-results").first(),this.is_multiple?(this.search_choices=this.container.find("ul.chzn-choices").first(),this.search_container=this.container.find("li.search-field").first()):(this.search_container=this.container.find("div.chzn-search").first(),this.selected_item=this.container.find(".chzn-single").first(),f=e-c(this.search_container)-c(this.search_field),this.search_field.css({width:f+"px"})),this.results_build();return this.set_tab_index()},b.prototype.register_observers=function(){this.container.mousedown(e(function(a){return this.container_mousedown(a)},this)),this.container.mouseenter(e(function(a){return this.mouse_enter(a)},this)),this.container.mouseleave(e(function(a){return this.mouse_leave(a)},this)),this.search_results.mouseup(e(function(a){return this.search_results_mouseup(a)},this)),this.search_results.mouseover(e(function(a){return this.search_results_mouseover(a)},this)),this.search_results.mouseout(e(function(a){return this.search_results_mouseout(a)},this)),this.form_field_jq.bind("liszt:updated",e(function(a){return this.results_update_field(a)},this)),this.search_field.blur(e(function(a){return this.input_blur(a)},this)),this.search_field.keyup(e(function(a){return this.keyup_checker(a)},this)),this.search_field.keydown(e(function(a){return this.keydown_checker(a)},this));if(this.is_multiple){this.search_choices.click(e(function(a){return this.choices_click(a)},this));return this.search_field.focus(e(function(a){return this.input_focus(a)},this))}},b.prototype.search_field_disabled=function(){this.is_disabled=this.form_field_jq.attr("disabled");if(this.is_disabled){this.container.addClass("chzn-disabled"),this.search_field.attr("disabled",!0),this.is_multiple||this.selected_item.unbind("focus",this.activate_action);return this.close_field()}this.container.removeClass("chzn-disabled"),this.search_field.attr("disabled",!1);if(!this.is_multiple)return this.selected_item.bind("focus",this.activate_action)},b.prototype.container_mousedown=function(b){if(!this.is_disabled){b&&b.type==="mousedown"&&b.stopPropagation();if(!this.pending_destroy_click){this.active_field?!this.is_multiple&&b&&(a(b.target)===this.selected_item||a(b.target).parents("a.chzn-single").length)&&(b.preventDefault(),this.results_toggle()):(this.is_multiple&&this.search_field.val(""),a(document).click(this.click_test_action),this.results_show());return this.activate_field()}return this.pending_destroy_click=!1}},b.prototype.mouse_enter=function(){return this.mouse_on_container=!0},b.prototype.mouse_leave=function(){return this.mouse_on_container=!1},b.prototype.input_focus=function(a){if(!this.active_field)return setTimeout(e(function(){return this.container_mousedown()},this),50)},b.prototype.input_blur=function(a){if(!this.mouse_on_container){this.active_field=!1;return setTimeout(e(function(){return this.blur_test()},this),100)}},b.prototype.blur_test=function(a){if(!this.active_field&&this.container.hasClass("chzn-container-active"))return this.close_field()},b.prototype.close_field=function(){a(document).unbind("click",this.click_test_action),this.is_multiple||(this.selected_item.attr("tabindex",this.search_field.attr("tabindex")),this.search_field.attr("tabindex",-1)),this.active_field=!1,this.results_hide(),this.container.removeClass("chzn-container-active"),this.winnow_results_clear(),this.clear_backstroke(),this.show_search_field_default();return this.search_field_scale()},b.prototype.activate_field=function(){!this.is_multiple&&!this.active_field&&(this.search_field.attr("tabindex",this.selected_item.attr("tabindex")),this.selected_item.attr("tabindex",-1)),this.container.addClass("chzn-container-active"),this.active_field=!0,this.search_field.val(this.search_field.val());return this.search_field.focus()},b.prototype.test_active_click=function(b){return a(b.target).parents("#"+this.container_id).length?this.active_field=!0:this.close_field()},b.prototype.results_build=function(){var a,b,c,e,f,g;c=new Date,this.parsing=!0,this.results_data=d.SelectParser.select_to_array(this.form_field),this.is_multiple&&this.choices>0?(this.search_choices.find("li.search-choice").remove(),this.choices=0):this.is_multiple||this.selected_item.find("span").text(this.default_text),a="",g=this.results_data;for(e=0,f=g.length;e'+a("
        ").text(b.label).html()+""}return""},b.prototype.result_add_option=function(a){var b;if(!a.disabled){a.dom_id=this.container_id+"_o_"+a.array_index,b=a.selected&&this.is_multiple?[]:["active-result"],a.selected&&b.push("result-selected"),a.group_array_index!=null&&b.push("group-option");return'
      • '+a.html+"
      • "}return""},b.prototype.results_update_field=function(){this.result_clear_highlight(),this.result_single_selected=null;return this.results_build()},b.prototype.result_do_highlight=function(a){var b,c,d,e,f;if(a.length){this.result_clear_highlight(),this.result_highlight=a,this.result_highlight.addClass("highlighted"),d=parseInt(this.search_results.css("maxHeight"),10),f=this.search_results.scrollTop(),e=d+f,c=this.result_highlight.position().top+this.search_results.scrollTop(),b=c+this.result_highlight.outerHeight();if(b>=e)return this.search_results.scrollTop(b-d>0?b-d:0);if(c'+b.html+''),d=a("#"+c).find("a").first();return d.click(e(function(a){return this.choice_destroy_link_click(a)},this))},b.prototype.choice_destroy_link_click=function(b){b.preventDefault();if(!this.is_disabled){this.pending_destroy_click=!0;return this.choice_destroy(a(b.target))}return b.stopPropagation},b.prototype.choice_destroy=function(a){this.choices-=1,this.show_search_field_default(),this.is_multiple&&this.choices>0&&this.search_field.val().length<1&&this.results_hide(),this.result_deselect(a.attr("rel"));return a.parents("li").first().remove()},b.prototype.result_select=function(a){var b,c,d,e;if(this.result_highlight){b=this.result_highlight,c=b.attr("id"),this.result_clear_highlight(),b.addClass("result-selected"),this.is_multiple?this.result_deactivate(b):this.result_single_selected=b,e=c.substr(c.lastIndexOf("_")+1),d=this.results_data[e],d.selected=!0,this.form_field.options[d.options_index].selected=!0,this.is_multiple?this.choice_build(d):this.selected_item.find("span").first().text(d.text),(!a.metaKey||!this.is_multiple)&&this.results_hide(),this.search_field.val(""),this.form_field_jq.trigger("change");return this.search_field_scale()}},b.prototype.result_activate=function(a){return a.addClass("active-result").show()},b.prototype.result_deactivate=function(a){return a.removeClass("active-result").hide()},b.prototype.result_deselect=function(b){var c,d;d=this.results_data[b],d.selected=!1,this.form_field.options[d.options_index].selected=!1,c=a("#"+this.container_id+"_o_"+b),c.removeClass("result-selected").addClass("active-result").show(),this.result_clear_highlight(),this.winnow_results(),this.form_field_jq.trigger("change");return this.search_field_scale()},b.prototype.results_search=function(a){return this.results_showing?this.winnow_results():this.results_show()},b.prototype.winnow_results=function(){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r;j=new Date,this.no_results_clear(),h=0,i=this.search_field.val()===this.default_text?"":a("
        ").text(a.trim(this.search_field.val())).html(),f=new RegExp("^"+i.replace(/[-[\]{}()*+?.,\\^$|#\s]/g,"\\$&"),"i"),m=new RegExp(i.replace(/[-[\]{}()*+?.,\\^$|#\s]/g,"\\$&"),"i"),r=this.results_data;for(n=0,p=r.length;n=0||c.html.indexOf("[")===0){e=c.html.replace(/\[|\]/g,"").split(" ");if(e.length)for(o=0,q=e.length;o"+c.html.substr(k+i.length),l=l.substr(0,k)+""+l.substr(k)):l=c.html,a("#"+g).html!==l&&a("#"+g).html(l),this.result_activate(a("#"+g)),c.group_array_index!=null&&a("#"+this.results_data[c.group_array_index].dom_id).show()):(this.result_highlight&&g===this.result_highlight.attr("id")&&this.result_clear_highlight(),this.result_deactivate(a("#"+g)))}}return h<1&&i.length?this.no_results(i):this.winnow_results_set_highlight()},b.prototype.winnow_results_clear=function(){var b,c,d,e,f;this.search_field.val(""),c=this.search_results.find("li"),f=[];for(d=0,e=c.length;d'+this.results_none_found+' ""'),c.find("span").first().html(b);return this.search_results.append(c)},b.prototype.no_results_clear=function(){return this.search_results.find(".no-results").remove()},b.prototype.keydown_arrow=function(){var b,c;this.result_highlight?this.results_showing&&(c=this.result_highlight.nextAll("li.active-result").first(),c&&this.result_do_highlight(c)):(b=this.search_results.find("li.active-result").first(),b&&this.result_do_highlight(a(b)));if(!this.results_showing)return this.results_show()},b.prototype.keyup_arrow=function(){var a;if(!this.results_showing&&!this.is_multiple)return this.results_show();if(this.result_highlight){a=this.result_highlight.prevAll("li.active-result");if(a.length)return this.result_do_highlight(a.first());this.choices>0&&this.results_hide();return this.result_clear_highlight()}},b.prototype.keydown_backstroke=function(){if(this.pending_backstroke){this.choice_destroy(this.pending_backstroke.find("a").first());return this.clear_backstroke()}this.pending_backstroke=this.search_container.siblings("li.search-choice").last();return this.pending_backstroke.addClass("search-choice-focus")},b.prototype.clear_backstroke=function(){this.pending_backstroke&&this.pending_backstroke.removeClass("search-choice-focus");return this.pending_backstroke=null},b.prototype.keyup_checker=function(a){var b,c;b=(c=a.which)!=null?c:a.keyCode,this.search_field_scale();switch(b){case 8:if(this.is_multiple&&this.backstroke_length<1&&this.choices>0)return this.keydown_backstroke();if(!this.pending_backstroke){this.result_clear_highlight();return this.results_search()}break;case 13:a.preventDefault();if(this.results_showing)return this.result_select(a);break;case 27:if(this.results_showing)return this.results_hide();break;case 9:case 38:case 40:case 16:case 91:case 17:break;default:return this.results_search()}},b.prototype.keydown_checker=function(a){var b,c;b=(c=a.which)!=null?c:a.keyCode,this.search_field_scale(),b!==8&&this.pending_backstroke&&this.clear_backstroke();switch(b){case 8:this.backstroke_length=this.search_field.val().length;break;case 9:this.mouse_on_container=!1;break;case 13:a.preventDefault();break;case 38:a.preventDefault(),this.keyup_arrow();break;case 40:this.keydown_arrow()}},b.prototype.search_field_scale=function(){var b,c,d,e,f,g,h,i,j;if(this.is_multiple){d=0,h=0,f="position:absolute; left: -1000px; top: -1000px; display:none;",g=["font-size","font-style","font-weight","font-family","line-height","text-transform","letter-spacing"];for(i=0,j=g.length;i",{style:f}),c.text(this.search_field.val()),a("body").append(c),h=c.width()+25,c.remove(),h>this.f_width-10&&(h=this.f_width-10),this.search_field.css({width:h+"px"}),b=this.container.height();return this.dropdown.css({top:b+"px"})}},b.prototype.generate_field_id=function(){var a;a=this.generate_random_id(),this.form_field.id=a;return a},b.prototype.generate_random_id=function(){var b;b="sel"+this.generate_random_char()+this.generate_random_char()+this.generate_random_char();while(a("#"+b).length>0)b+=this.generate_random_char();return b},b.prototype.generate_random_char=function(){var a,b,c;a="0123456789ABCDEFGHIJKLMNOPQRSTUVWXTZ",c=Math.floor(Math.random()*a.length);return b=a.substring(c,c+1)};return b}(),c=function(a){var b;return b=a.outerWidth()-a.width()},d.get_side_border_padding=c}).call(this),function(){var a;a=function(){function a(){this.options_index=0,this.parsed=[]}a.prototype.add_node=function(a){return a.nodeName==="OPTGROUP"?this.add_group(a):this.add_option(a)},a.prototype.add_group=function(a){var b,c,d,e,f,g;b=this.parsed.length,this.parsed.push({array_index:b,group:!0,label:a.label,children:0,disabled:a.disabled}),f=a.childNodes,g=[];for(d=0,e=f.length;d').appendTo(document.body)[0]; 29 | var image = $('').appendTo(document.body)[0]; 30 | 31 | function removeVScrollbar(imageData, callback) { 32 | var ctx = canvas.getContext('2d'); 33 | 34 | image.src = imageData; 35 | 36 | image.onload = function(){ 37 | canvas.width = image.naturalWidth - getScrollbarWidth(); 38 | canvas.height = image.naturalHeight; 39 | 40 | ctx.drawImage(image, 0, 0, 41 | image.naturalWidth, image.naturalHeight); 42 | 43 | callback(canvas.toDataURL()); 44 | } 45 | } 46 | 47 | 48 | var anim = new Animation(document.getElementById('img'), document.getElementById('canvas'), 11); 49 | 50 | browser.popupHeight = 400; 51 | browser.popupWidth = 400; 52 | 53 | function createGalleryClick(data) { 54 | anim.start(); 55 | 56 | Minus.getFileHeader(data.srcUrl, function(headers){ 57 | // Gif file editing is forbided 58 | if (store.get('edit_image') && headers.mime != "image/gif") { 59 | anim.stop(); 60 | 61 | window.latest_screenshot = data.srcUrl; 62 | browser.tabs.create({ url: browser.extension.getURL('/edit_image.html?title='+data.srcUrl) }); 63 | } else { 64 | uploadScreenshot(data.srcUrl, '', data.srcUrl); 65 | } 66 | }); 67 | } 68 | 69 | function captureFromMenu(captureType) { 70 | listener({ method: 'takeScreenshot', captureType: captureType }); 71 | } 72 | 73 | function listenForUsernameChange() { 74 | if (window.last_username != window.store.get('username')) { 75 | initContextMenu(); 76 | } 77 | 78 | window.last_username = window.store.get('username'); 79 | } 80 | 81 | setInterval(listenForUsernameChange, 5000); 82 | 83 | function initContextMenu() { 84 | if (browser.isChrome || browser.isFirefox) { 85 | chrome.contextMenus.removeAll(function(){ 86 | if (window.store.get('username')) { 87 | browser.contextMenus.create({ 88 | "title": "Upload to Minus", 89 | "onclick" : createGalleryClick, 90 | "contexts":["image"] 91 | }); 92 | 93 | browser.contextMenus.create({ 94 | "title": "Capture Visible Part of Page", 95 | "onclick" : function(){ captureFromMenu('visible') } 96 | }); 97 | 98 | browser.contextMenus.create({ 99 | "title": "Capture Selected Area", 100 | "onclick" : function(){ captureFromMenu('region') }, 101 | "documentUrlPatterns": ["http://*/*"] 102 | }); 103 | 104 | browser.contextMenus.create({ 105 | "title": "Capture Entire Page", 106 | "onclick" : function(){ captureFromMenu('full') }, 107 | "documentUrlPatterns": ["http://*/*"] 108 | }); 109 | } else { 110 | browser.contextMenus.create({ 111 | "title": "Not logged to Minus", 112 | "onclick" : function(){} 113 | }); 114 | } 115 | }); 116 | 117 | 118 | } else if(browser.isSafari) { 119 | function handleContextMenu(event) { 120 | if (event.userInfo.nodeName === "IMG") { 121 | event.contextMenu.appendContextMenuItem("context_menu_1", "Upload to Minus"); 122 | } 123 | } 124 | 125 | safari.application.addEventListener("contextmenu", handleContextMenu, false); 126 | 127 | safari.application.addEventListener("command", function(event) { 128 | if (event.command == "context_menu_1") { 129 | createGalleryClick(event.userInfo); 130 | } 131 | }, false); 132 | } 133 | } 134 | 135 | function uploadItem(binaryData, gallery_id, title, onProgress){ 136 | anim.start(); 137 | 138 | if (!title) title = "Untitled"; 139 | 140 | Minus.uploadItem(gallery_id, title.slice(0,50), "image/png", binaryData, 141 | function(resp){ 142 | anim.stop(); 143 | 144 | browser.toolbarItem.setText(''); 145 | 146 | console.log('resp'); 147 | 148 | if (!resp.error) 149 | browser.tabs.create({ url: "http://minus.com/m"+gallery_id }); 150 | 151 | browser.postMessage({ method: "uploadComplete" }); 152 | }, 153 | 154 | onProgress 155 | ); 156 | } 157 | 158 | function uploadScreenshot(base64Data, gallery_id, title) { 159 | Minus.setUser(window.store.get('username')); 160 | Minus.setToken(window.store.get('access_token')); 161 | 162 | var onProgress = function(progress) { 163 | console.log('updating progress'); 164 | 165 | var percent = parseInt(progress)+'%'; 166 | browser.toolbarItem.setText(percent); 167 | 168 | browser.postMessage({ method:"uploadProgress", progress: progress }); 169 | } 170 | 171 | function upload() { 172 | var binaryData = atob(base64Data.replace(/^data\:image\/png\;base64\,/,'')); 173 | 174 | if (!gallery_id) { 175 | Minus.createGallery(null, function(gallery) { 176 | uploadItem(binaryData, gallery.id, title, onProgress); 177 | }); 178 | } else { 179 | uploadItem(binaryData, gallery_id, title, onProgress); 180 | } 181 | } 182 | 183 | if (base64Data.slice(0,4) == 'data') { 184 | upload(); 185 | } else { 186 | anim.start(); 187 | 188 | Minus.createGallery(null, function(gallery) { 189 | Minus.uploadItemFromURL(base64Data, gallery.id, function(resp){ 190 | anim.stop(); 191 | 192 | browser.toolbarItem.setText(''); 193 | 194 | if (!resp.error) 195 | browser.tabs.create({ url: "http://minus.com/m"+gallery.id }); 196 | 197 | browser.postMessage({ method: "uploadComplete" }); 198 | }, onProgress); 199 | }); 200 | } 201 | } 202 | 203 | function captureVisible(callback) { 204 | browser.tabs.captureVisibleTab(null, {format: 'png'}, function(dataUrl) { 205 | callback(dataUrl); 206 | }); 207 | } 208 | 209 | function concatImages(image_data_array, callback) { 210 | if (!$.isArray(image_data_array)) 211 | return false; 212 | 213 | var images = [], 214 | image, 215 | loaded_images = 0, 216 | total_height = 0, 217 | total_width = 0, 218 | concated_height = 0; 219 | 220 | var canvas = $('').appendTo(document.body); 221 | 222 | var imageLoaded = function() { 223 | total_width = this.naturalWidth; 224 | total_height = total_height + this.naturalHeight; 225 | 226 | loaded_images += 1; 227 | 228 | // All images loaded 229 | if (loaded_images == image_data_array.length) { 230 | canvas[0].width = total_width; 231 | canvas[0].height = total_height; 232 | ctx = canvas[0].getContext('2d'); 233 | 234 | for (var i=0; i').appendTo(document.body); 261 | ctx = canvas[0].getContext('2d'); 262 | 263 | var image = new Image; 264 | image.src = imageData; 265 | image.onload = function(){ 266 | canvas[0].width = image.naturalWidth; 267 | canvas[0].height = image.naturalHeight - heightFix; 268 | 269 | ctx.drawImage(image, 0, -heightFix); 270 | callback(canvas[0].toDataURL()); 271 | 272 | canvas.remove(); 273 | } 274 | } 275 | 276 | function cropImage(bounds, imageData, callback) { 277 | var canvas = $('').appendTo(document.body); 278 | ctx = canvas[0].getContext('2d'); 279 | 280 | var image = new Image; 281 | image.src = imageData; 282 | image.onload = function(){ 283 | canvas[0].width = bounds.width; 284 | canvas[0].height = bounds.height; 285 | 286 | ctx.drawImage(image, bounds.left, bounds.top, bounds.width, bounds.height, 0, 0, bounds.width, bounds.height); 287 | callback(canvas[0].toDataURL()); 288 | 289 | canvas.remove() 290 | } 291 | } 292 | 293 | function updateSettings(receiver) { 294 | var settings = {}; 295 | settings[store.get('hotkey_visible')||'V'] = 'visible'; 296 | settings[store.get('hotkey_region')||'R'] = 'region'; 297 | settings[store.get('hotkey_ffll')||'H'] = 'full'; 298 | 299 | console.log(receiver); 300 | 301 | browser.postMessage({ method: 'updateSettings', settings: settings }, receiver); 302 | } 303 | 304 | var listener = function(msg, sender, sendResponse) { 305 | console.log('Received message', msg); 306 | 307 | switch (msg.method) { 308 | case 'takeScreenshot': 309 | anim.start(); 310 | 311 | browser.tabs.getSelected(null, function(tab) { 312 | window.latest_title = tab.title; 313 | 314 | switch (msg.captureType) { 315 | case 'visible': 316 | captureVisible(function(dataUrl){ 317 | removeVScrollbar(dataUrl, function(imageData){ 318 | window.latest_screenshot = imageData; 319 | 320 | if (store.get('edit_image')) { 321 | anim.stop(); 322 | 323 | browser.postMessage({ method: "screenshotComplete" }); 324 | browser.tabs.create({ url: browser.extension.getURL('/edit_image.html?title='+encodeURIComponent(tab.title)) }); 325 | } else { 326 | uploadScreenshot(imageData, '', tab.title) 327 | } 328 | }); 329 | }); 330 | 331 | break; 332 | case 'full': 333 | window.latest_screenshot = []; 334 | browser.postMessage({ method: "scroll", initial: true }, tab); 335 | break; 336 | 337 | case 'scroll': 338 | captureVisible(function(imageData){ 339 | if (msg.finished) { 340 | concatImages(window.latest_screenshot, function(image){ 341 | removeVScrollbar(image, function(imageData){ 342 | window.latest_screenshot = imageData; 343 | 344 | if (store.get('edit_image')) { 345 | anim.stop(); 346 | 347 | browser.tabs.create({ url: browser.extension.getURL('/edit_image.html?title='+tab.title) }); 348 | browser.postMessage({ method: "screenshotComplete" }); 349 | } else { 350 | uploadScreenshot(imageData, '', tab.title) 351 | } 352 | }); 353 | }); 354 | } else { 355 | cropHeight(msg.heightFix, imageData, function(image){ 356 | window.latest_screenshot.push(image); 357 | 358 | browser.postMessage({ method: "scroll" }, tab); 359 | }); 360 | } 361 | }); 362 | break; 363 | 364 | case 'region': 365 | anim.stop(); 366 | 367 | if (msg.finished) { 368 | captureVisible(function(imageData) { 369 | cropImage(msg.bounds, imageData, function(image){ 370 | window.latest_screenshot = image; 371 | 372 | if (store.get('edit_image')) { 373 | browser.tabs.create({ url: browser.extension.getURL('/edit_image.html?title='+tab.title) }); 374 | browser.postMessage({ method: "screenshotComplete" }); 375 | } else { 376 | uploadScreenshot(image, '', tab.title) 377 | } 378 | }); 379 | }); 380 | } else { 381 | browser.postMessage({ method: 'region' }, tab); 382 | } 383 | break; 384 | } 385 | }); 386 | break; 387 | 388 | case 'uploadScreenshot': 389 | uploadScreenshot(msg.imageData, msg.gallery, msg.title); 390 | 391 | break; 392 | 393 | case 'setUsername': 394 | store.set('username', msg.username); 395 | 396 | browser.postMessage({ method: 'setUsername', username: msg.username }); 397 | 398 | break; 399 | 400 | case 'updateSettings': 401 | updateSettings(msg.global ? undefined : sender.tab); 402 | 403 | break; 404 | 405 | case 'timeline': 406 | Minus.timeline(msg.username, msg.timeline, msg.page, 407 | function(resp) { 408 | sendResponse(resp); 409 | } 410 | ); 411 | 412 | break; 413 | 414 | case 'getCaptureData': 415 | console.log('getting capture data', sendResponse); 416 | 417 | sendResponse({ 418 | response: { 419 | data: window.latest_screenshot, 420 | tabtitle: window.latest_title 421 | } 422 | }); 423 | break; 424 | 425 | case 'getSettings': 426 | sendResponse({ 427 | response: { 428 | settings: { 429 | shortcuts: { 430 | visible: { key: (store.get('hotkey_visible')||'V') }, 431 | 432 | region: { key: (store.get('hotkey_region')||'R') }, 433 | 434 | entire: { key: (store.get('hotkey_full')||'H') } 435 | } 436 | } 437 | } 438 | }); 439 | break; 440 | 441 | case 'updateHotkeys': 442 | console.log('setting key', msg.settings.hotkey_region); 443 | 444 | store.set('hotkey_visible', msg.settings.hotkey_visible); 445 | store.set('hotkey_region', msg.settings.hotkey_region); 446 | store.set('hotkey_full', msg.settings.hotkey_entire); 447 | 448 | updateSettings(); 449 | break; 450 | 451 | case '_ajax': 452 | var xhr; 453 | var send = function() { 454 | console.log('sending response', sendResponse); 455 | 456 | sendResponse({ 457 | status: xhr.status, 458 | responseText: xhr.responseText, 459 | responseHeaders: xhr.getAllResponseHeaders() 460 | }); 461 | }; 462 | 463 | xhr = new Minus.Ajax(msg.httpOptions.url, { 464 | method: msg.httpOptions.method, 465 | headers: msg.httpOptions.headers, 466 | binaryData: msg.httpOptions.binary ? msg.httpOptions.data : null, 467 | params: msg.httpOptions.binary ? null : msg.httpOptions.data, 468 | 469 | onSuccess: send, 470 | onError: send 471 | }); 472 | } 473 | } 474 | 475 | 476 | function refreshToken(){ 477 | console.log('adada'); 478 | 479 | if (!window.store.get('refresh_token')) return; 480 | 481 | Minus.refreshToken(window.store.get('refresh_token'), 482 | function(resp) { 483 | if (resp.access_token) { 484 | window.store.set('access_token', resp.access_token); 485 | window.store.set('refresh_token', resp.refresh_token); 486 | } 487 | } 488 | ); 489 | 490 | setTimeout(refreshToken, 1000*60*30); 491 | } 492 | 493 | refreshToken(); 494 | 495 | browser.addMessageListener(listener); 496 | 497 | function executeInExistingTabs(){ 498 | chrome.windows.getAll(null, function(wins) { 499 | for (var j = 0; j < wins.length; ++j) { 500 | chrome.tabs.getAllInWindow(wins[j].id, function(tabs) { 501 | for (var i = 0; i < tabs.length; ++i) { 502 | if (tabs[i].url.match('chrome://') || tabs[i].url.match('chrome-devtools://')) 503 | continue; 504 | 505 | try { 506 | chrome.tabs.executeScript(tabs[i].id, { file: 'js/jquery.min.js' }); 507 | chrome.tabs.executeScript(tabs[i].id, { file: 'js/browser_api.js' }); 508 | chrome.tabs.executeScript(tabs[i].id, { file: 'js/content_script.js' }); 509 | 510 | chrome.tabs.insertCSS(tabs[i].id, { file: 'css/reset-context-min.css' }); 511 | chrome.tabs.insertCSS(tabs[i].id, { file: 'css/page.css' }); 512 | } catch(e) {} 513 | } 514 | }); 515 | } 516 | }); 517 | } 518 | 519 | browser.onReady(function(){ 520 | initContextMenu(); 521 | executeInExistingTabs(); 522 | updateSettings(); 523 | }); 524 | 525 | }()); 526 | --------------------------------------------------------------------------------