├── .gitignore ├── data ├── images │ ├── gear.png │ ├── logo.png │ ├── bottom.png │ ├── loading.gif │ ├── logo16.png │ ├── logo_37.png │ ├── logo_64.png │ ├── scroll.png │ ├── signup.png │ ├── button_bg.png │ ├── dashboard.png │ ├── ic_public.png │ ├── logo_128.png │ ├── logo_anim.gif │ ├── logo_big.png │ ├── logo_gray.png │ ├── popup_bg.png │ ├── popup_new.png │ ├── separator.png │ ├── signup_bg.png │ ├── ajax-loader.gif │ ├── bottom_logo.png │ ├── generic_file.png │ ├── ic_private.png │ ├── logo16_anim.gif │ ├── logo_large.png │ ├── logo_small.png │ ├── more_content.png │ ├── popup_logo.png │ ├── public_bage.png │ ├── create_folder.png │ ├── logo_small_bw.png │ ├── upload_button.png │ ├── btn_camera_gray.png │ ├── btn_camera_normal.png │ ├── choose_gallery_bg.png │ ├── dropdown_arrow_up.png │ ├── edit_image_logo.png │ ├── edit_image_panel.png │ ├── logo_anim_sprite.png │ ├── logo_small_clean.png │ ├── take_screenshot.png │ ├── choose_gallery_new.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 ├── js │ ├── minus_auth.js │ ├── canvas_animation.js │ ├── jquery.mousewheel.js │ ├── store.js │ ├── jquery.timeago.js │ ├── jquery.tmpl.min.js │ ├── portamento.js │ ├── popup.js │ ├── content_script.js │ ├── minus.js │ ├── background.js │ └── chosen.jquery.min.js ├── background.html ├── message_bridge.js ├── options.html ├── popup.html └── edit_image.html ├── README.md ├── doc └── main.md ├── package.json ├── lib ├── upload.js ├── main.js └── ui.js └── test └── test-main.js /.gitignore: -------------------------------------------------------------------------------- 1 | *~ 2 | *.sw* 3 | -------------------------------------------------------------------------------- /data/images/gear.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buger/minus-firefox/master/data/images/gear.png -------------------------------------------------------------------------------- /data/images/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buger/minus-firefox/master/data/images/logo.png -------------------------------------------------------------------------------- /data/images/bottom.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buger/minus-firefox/master/data/images/bottom.png -------------------------------------------------------------------------------- /data/images/loading.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buger/minus-firefox/master/data/images/loading.gif -------------------------------------------------------------------------------- /data/images/logo16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buger/minus-firefox/master/data/images/logo16.png -------------------------------------------------------------------------------- /data/images/logo_37.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buger/minus-firefox/master/data/images/logo_37.png -------------------------------------------------------------------------------- /data/images/logo_64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buger/minus-firefox/master/data/images/logo_64.png -------------------------------------------------------------------------------- /data/images/scroll.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buger/minus-firefox/master/data/images/scroll.png -------------------------------------------------------------------------------- /data/images/signup.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buger/minus-firefox/master/data/images/signup.png -------------------------------------------------------------------------------- /data/images/button_bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buger/minus-firefox/master/data/images/button_bg.png -------------------------------------------------------------------------------- /data/images/dashboard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buger/minus-firefox/master/data/images/dashboard.png -------------------------------------------------------------------------------- /data/images/ic_public.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buger/minus-firefox/master/data/images/ic_public.png -------------------------------------------------------------------------------- /data/images/logo_128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buger/minus-firefox/master/data/images/logo_128.png -------------------------------------------------------------------------------- /data/images/logo_anim.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buger/minus-firefox/master/data/images/logo_anim.gif -------------------------------------------------------------------------------- /data/images/logo_big.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buger/minus-firefox/master/data/images/logo_big.png -------------------------------------------------------------------------------- /data/images/logo_gray.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buger/minus-firefox/master/data/images/logo_gray.png -------------------------------------------------------------------------------- /data/images/popup_bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buger/minus-firefox/master/data/images/popup_bg.png -------------------------------------------------------------------------------- /data/images/popup_new.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buger/minus-firefox/master/data/images/popup_new.png -------------------------------------------------------------------------------- /data/images/separator.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buger/minus-firefox/master/data/images/separator.png -------------------------------------------------------------------------------- /data/images/signup_bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buger/minus-firefox/master/data/images/signup_bg.png -------------------------------------------------------------------------------- /data/css/chosen-sprite.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buger/minus-firefox/master/data/css/chosen-sprite.png -------------------------------------------------------------------------------- /data/images/ajax-loader.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buger/minus-firefox/master/data/images/ajax-loader.gif -------------------------------------------------------------------------------- /data/images/bottom_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buger/minus-firefox/master/data/images/bottom_logo.png -------------------------------------------------------------------------------- /data/images/generic_file.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buger/minus-firefox/master/data/images/generic_file.png -------------------------------------------------------------------------------- /data/images/ic_private.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buger/minus-firefox/master/data/images/ic_private.png -------------------------------------------------------------------------------- /data/images/logo16_anim.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buger/minus-firefox/master/data/images/logo16_anim.gif -------------------------------------------------------------------------------- /data/images/logo_large.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buger/minus-firefox/master/data/images/logo_large.png -------------------------------------------------------------------------------- /data/images/logo_small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buger/minus-firefox/master/data/images/logo_small.png -------------------------------------------------------------------------------- /data/images/more_content.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buger/minus-firefox/master/data/images/more_content.png -------------------------------------------------------------------------------- /data/images/popup_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buger/minus-firefox/master/data/images/popup_logo.png -------------------------------------------------------------------------------- /data/images/public_bage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buger/minus-firefox/master/data/images/public_bage.png -------------------------------------------------------------------------------- /data/images/create_folder.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buger/minus-firefox/master/data/images/create_folder.png -------------------------------------------------------------------------------- /data/images/logo_small_bw.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buger/minus-firefox/master/data/images/logo_small_bw.png -------------------------------------------------------------------------------- /data/images/upload_button.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buger/minus-firefox/master/data/images/upload_button.png -------------------------------------------------------------------------------- /data/images/btn_camera_gray.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buger/minus-firefox/master/data/images/btn_camera_gray.png -------------------------------------------------------------------------------- /data/images/btn_camera_normal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buger/minus-firefox/master/data/images/btn_camera_normal.png -------------------------------------------------------------------------------- /data/images/choose_gallery_bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buger/minus-firefox/master/data/images/choose_gallery_bg.png -------------------------------------------------------------------------------- /data/images/dropdown_arrow_up.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buger/minus-firefox/master/data/images/dropdown_arrow_up.png -------------------------------------------------------------------------------- /data/images/edit_image_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buger/minus-firefox/master/data/images/edit_image_logo.png -------------------------------------------------------------------------------- /data/images/edit_image_panel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buger/minus-firefox/master/data/images/edit_image_panel.png -------------------------------------------------------------------------------- /data/images/logo_anim_sprite.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buger/minus-firefox/master/data/images/logo_anim_sprite.png -------------------------------------------------------------------------------- /data/images/logo_small_clean.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buger/minus-firefox/master/data/images/logo_small_clean.png -------------------------------------------------------------------------------- /data/images/take_screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buger/minus-firefox/master/data/images/take_screenshot.png -------------------------------------------------------------------------------- /data/images/choose_gallery_new.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buger/minus-firefox/master/data/images/choose_gallery_new.png -------------------------------------------------------------------------------- /data/images/dropdown_arrow_down.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buger/minus-firefox/master/data/images/dropdown_arrow_down.png -------------------------------------------------------------------------------- /data/images/more_content_pressed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buger/minus-firefox/master/data/images/more_content_pressed.png -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | This is the minus-firefox add-on. It contains: 2 | 3 | * A program (lib/main.js). 4 | * A few tests. 5 | * Some meager documentation. 6 | -------------------------------------------------------------------------------- /doc/main.md: -------------------------------------------------------------------------------- 1 | The main module is a program that creates a widget. When a user clicks on 2 | the widget, the program loads the mozilla.org website in a new tab. 3 | -------------------------------------------------------------------------------- /data/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 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "minus_ff", 3 | "author": "Minus.com", 4 | "version": "1.7", 5 | "icon": "data/images/logo_64.png", 6 | "icon64": "data/images/logo_64.png", 7 | "fullName": "Minus - Share simply", 8 | "id": "jid0-IqTRXaCOez4eRl9nE76oWp1G2iE", 9 | "description": "The simplest and free way to share share pictures, documents, music, videos and files fast, easy, and fun. Minus is the universal sharing platform." 10 | } 11 | -------------------------------------------------------------------------------- /data/background.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /lib/upload.js: -------------------------------------------------------------------------------- 1 | var request = require('request'); 2 | 3 | /* var api = { 4 | cmd : 'imageUpload', 5 | pv : '1.0', 6 | cv : '1.0', 7 | ct : 'firefox', 8 | url : 'http://awesomescreenshot.com/client?' 9 | }; 10 | 11 | function sendRequest(message, callback) { 12 | request.Request({ 13 | url: api.url + 'cmd=' + api.cmd + '&pv=' + api.pv + '&ct=' + api.ct + '&cv=' + api.cv, 14 | content: JSON.stringify(message.data), 15 | onComplete: callback 16 | }).post(); 17 | } */ 18 | 19 | function sendRequest(message, callback) { 20 | request.Request({ 21 | url: message.url, // string 22 | content: message.data, // object 23 | onComplete: callback 24 | }).post(); 25 | } 26 | 27 | exports.request = sendRequest; -------------------------------------------------------------------------------- /data/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;} -------------------------------------------------------------------------------- /test/test-main.js: -------------------------------------------------------------------------------- 1 | const main = require("main"); 2 | 3 | exports.test_test_run = function(test) { 4 | test.pass("Unit test running!"); 5 | }; 6 | 7 | exports.test_id = function(test) { 8 | test.assert(require("self").id.length > 0); 9 | }; 10 | 11 | exports.test_url = function(test) { 12 | require("request").Request({ 13 | url: "http://www.mozilla.org/", 14 | onComplete: function(response) { 15 | test.assertEqual(response.statusText, "OK"); 16 | test.done(); 17 | } 18 | }).get(); 19 | test.waitUntilDone(20000); 20 | }; 21 | 22 | exports.test_open_tab = function(test) { 23 | const tabs = require("tabs"); 24 | tabs.open({ 25 | url: "http://www.mozilla.org/", 26 | onReady: function(tab) { 27 | test.assertEqual(tab.url, "http://www.mozilla.org/"); 28 | test.done(); 29 | } 30 | }); 31 | test.waitUntilDone(20000); 32 | }; 33 | -------------------------------------------------------------------------------- /data/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 | -------------------------------------------------------------------------------- /data/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 | -------------------------------------------------------------------------------- /data/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;} -------------------------------------------------------------------------------- /data/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 | -------------------------------------------------------------------------------- /data/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); -------------------------------------------------------------------------------- /data/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 | -------------------------------------------------------------------------------- /data/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 | 94 | 95 | 96 | -------------------------------------------------------------------------------- /data/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 != 'string') { 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) { storage.setItem(key, api.serialize(val)) } 67 | api.get = function(key) { return api.deserialize(storage.getItem(key)) } 68 | api.remove = function(key) { storage.removeItem(key) } 69 | api.clear = function() { storage.clear() } 70 | 71 | } else if (isGlobalStorageNameSupported()) { 72 | storage = win[globalStorageName][win.location.hostname] 73 | api.set = function(key, val) { storage[key] = api.serialize(val) } 74 | api.get = function(key) { return api.deserialize(storage[key] && storage[key].value) } 75 | api.remove = function(key) { delete storage[key] } 76 | api.clear = function() { for (var key in storage ) { delete storage[key] } } 77 | 78 | } else if (doc.documentElement.addBehavior) { 79 | var storage = doc.createElement('div') 80 | function withIEStorage(storeFunction) { 81 | return function() { 82 | var args = Array.prototype.slice.call(arguments, 0) 83 | args.unshift(storage) 84 | // See http://msdn.microsoft.com/en-us/library/ms531081(v=VS.85).aspx 85 | // and http://msdn.microsoft.com/en-us/library/ms531424(v=VS.85).aspx 86 | doc.body.appendChild(storage) 87 | storage.addBehavior('#default#userData') 88 | storage.load(localStorageName) 89 | var result = storeFunction.apply(api, args) 90 | doc.body.removeChild(storage) 91 | return result 92 | } 93 | } 94 | api.set = withIEStorage(function(storage, key, val) { 95 | storage.setAttribute(key, api.serialize(val)) 96 | storage.save(localStorageName) 97 | }) 98 | api.get = withIEStorage(function(storage, key) { 99 | return api.deserialize(storage.getAttribute(key)) 100 | }) 101 | api.remove = withIEStorage(function(storage, key) { 102 | storage.removeAttribute(key) 103 | storage.save(localStorageName) 104 | }) 105 | api.clear = withIEStorage(function(storage) { 106 | var attributes = storage.XMLDocument.documentElement.attributes 107 | storage.load(localStorageName) 108 | for (var i=0, attr; attr = attributes[i]; i++) { 109 | storage.removeAttribute(attr.name) 110 | } 111 | storage.save(localStorageName) 112 | }) 113 | } 114 | 115 | try { 116 | api.set(namespace, namespace) 117 | if (api.get(namespace) != namespace) { api.disabled = true } 118 | api.remove(namespace) 119 | } catch(e) { 120 | api.disabled = true 121 | } 122 | 123 | return api 124 | })(); 125 | -------------------------------------------------------------------------------- /data/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 | -------------------------------------------------------------------------------- /data/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) -------------------------------------------------------------------------------- /data/popup.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 70 | 71 | 72 | 98 | 99 | 100 |
101 | 134 | 135 |
136 | Dashboard 137 | 138 | My Files 139 | 142 |
143 | 144 |
145 |
    146 |
  • 147 |
148 |
149 | 154 |
155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | -------------------------------------------------------------------------------- /lib/main.js: -------------------------------------------------------------------------------- 1 | var self = require('self'); 2 | var tabs = require('tabs'); 3 | var pageMod = require('page-mod'); 4 | var ui = require('ui'); 5 | var request = require('request'); 6 | var ss = require("simple-storage"); 7 | var storage = ss.storage; 8 | var data = self.data; 9 | var captureData; 10 | 11 | var xhr = require('xhr'); 12 | var {Cc, Ci, Cu} = require("chrome"); 13 | var mediator = Cc['@mozilla.org/appshell/window-mediator;1'] 14 | .getService(Ci.nsIWindowMediator); 15 | var wnd = mediator.getMostRecentWindow("navigator:browser").wrappedJSObject; 16 | 17 | 18 | function createGallery(callback) { 19 | request.Request({ 20 | url: "http://minus.com/api/v2/users/"+storage.data.username+"/folders?bearer_token="+storage.data.access_token, 21 | 22 | content: { 'name': 'New Folder' }, 23 | 24 | onComplete: function(resp) { 25 | callback(resp.json); 26 | } 27 | }).post(); 28 | } 29 | 30 | function hashToQueryString(hash) { 31 | var params = []; 32 | 33 | for (key in hash) { 34 | if (hash.hasOwnProperty(key)) { 35 | params.push(key + "=" + hash[key]); 36 | } 37 | } 38 | 39 | return params.join('&'); 40 | } 41 | 42 | function uploadItem(id, filename, mime, base64Data, callback) { 43 | var binaryData = wnd.atob(base64Data.replace(/^data\:image\/png\;base64\,/,'')); 44 | 45 | filename = encodeURIComponent(filename.replace(/^\./,'')); 46 | 47 | var params = hashToQueryString({ 'bearer_token': storage.data.access_token }); 48 | 49 | var boundary = '---------------------------'; 50 | boundary += Math.floor(Math.random()*32768); 51 | boundary += Math.floor(Math.random()*32768); 52 | boundary += Math.floor(Math.random()*32768); 53 | 54 | var data = '--' + boundary + "\r\n"; 55 | data += 'Content-Disposition: form-data; name="file"; filename="' + filename + '"' + "\r\n"; 56 | data += 'Content-Type: ' + mime + "\r\n\r\n"; 57 | data += binaryData; 58 | data += "\r\n"; 59 | data += "\r\n" + '--' + boundary + "\r\n"; 60 | 61 | data += 'Content-Disposition: form-data; name="caption"'; 62 | data += "\r\n"; 63 | data += "\r\n"; 64 | data += filename; 65 | data += "\r\n" + '--' + boundary + "\r\n"; 66 | data += 'Content-Disposition: form-data; name="filename"'; 67 | data += "\r\n"; 68 | data += "\r\n"; 69 | data += filename 70 | data += "\r\n" + '--' + boundary + '--' 71 | data += "\r\n"; 72 | 73 | 74 | var url = "http://minus.com/api/v2/folders/"+id+"/files?"+params; 75 | 76 | var request; 77 | 78 | request = new xhr.XMLHttpRequest(); 79 | request.open("POST", url, true); 80 | 81 | request.onreadystatechange = function () { 82 | if (request.readyState == 4) { 83 | console.log("Status:", id, request.status, url, request.responseText); 84 | 85 | callback(id); 86 | } 87 | } 88 | request.setRequestHeader('Content-Type', 'multipart/form-data; boundary=' + boundary); 89 | 90 | request.sendAsBinary(data); 91 | } 92 | 93 | function extend(destination, source) { 94 | for (var property in source) { 95 | if (source.hasOwnProperty(property)) { 96 | destination[property] = source[property]; 97 | } 98 | } 99 | return destination; 100 | } 101 | 102 | var workers = []; 103 | 104 | function broadcastMessage(msg) { 105 | for (var i=0; i'); 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); -------------------------------------------------------------------------------- /data/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_preloader.src = $(img).data('image'); 73 | 74 | img_preloader.onload = function(){ 75 | if (img_preloader.naturalHeight == 0) { 76 | img.src = ICON_ARCHIVE; 77 | } else { 78 | img.src = img_preloader.src; 79 | } 80 | 81 | imageLoaded(); 82 | } 83 | 84 | img_preloader.onerror = function(){ 85 | img.src = ICON_ARCHIVE; 86 | 87 | imageLoaded(); 88 | } 89 | }); 90 | 91 | var pane = $("#galleries_container").data('jsp'); 92 | 93 | if (pane) { 94 | pane.reinitialise(); 95 | } else { 96 | $("#galleries_container") 97 | .jScrollPane({ 98 | maintainPosition: true, 99 | verticalDragMinHeight: 87, 100 | verticalDragMaxHeight: 87 101 | }); 102 | } 103 | 104 | $("#galleries_container") 105 | .unbind('jsp-scroll-y') 106 | .bind( 107 | 'jsp-scroll-y', 108 | function(event, scrollPositionX, isAtLeft, isAtRight) { 109 | // Load next page 110 | if (isAtRight) { 111 | if (current_page < total_pages) { 112 | current_page += 1; 113 | 114 | $('#my_galleries').append("
  • "); 115 | 116 | updateGalleries(current_page); 117 | } 118 | 119 | reinitializePane(); 120 | } 121 | } 122 | ); 123 | 124 | }); 125 | } 126 | 127 | browser.addMessageListener(function(msg, sender) { 128 | $('#header').removeClass('loading'); 129 | 130 | if (msg.method == "screenshotComplete") { 131 | updateTimeline(); 132 | } else { 133 | //updateUser(); 134 | } 135 | }); 136 | 137 | $('#take_screenshot').live('click', function(){ 138 | var parent = $(this).parent(); 139 | 140 | if (!parent.hasClass('loading')) { 141 | var screenshot_type = parent.find('li').data('screenshot-type'); 142 | 143 | if (screenshot_type) { 144 | parent.addClass('loading'); 145 | 146 | browser.postMessage({ method: 'takeScreenshot', captureType: screenshot_type }); 147 | 148 | if (screenshot_type == 'region') { 149 | setTimeout(window.close, 100); 150 | } 151 | } 152 | } 153 | }); 154 | 155 | $('#header .more li[data-screenshot-type]').live('click', function(){ 156 | if (!$('#header').hasClass('loading')) { 157 | $('#header').addClass('loading'); 158 | 159 | browser.postMessage({ method: 'takeScreenshot', captureType: $(this).data('screenshot-type') }); 160 | 161 | if ($(this).data('screenshot-type') == 'region') 162 | setTimeout(window.close, 100); 163 | } 164 | }); 165 | 166 | $('#header .more').hover( 167 | function(){ 168 | clearInterval(this.timer); 169 | $(this).addClass('hover') 170 | .find('div').show(); 171 | }, 172 | function(){ 173 | var self = $(this); 174 | 175 | this.timer = setTimeout(function(){ 176 | self.removeClass('hover') 177 | .find('div').hide(); 178 | }, 500); 179 | } 180 | ); 181 | 182 | function authUser() { 183 | var $form = $('#signin form.signin'); 184 | var form_data = $form.serializeArray(); 185 | 186 | Minus.oauthToken(form_data[0].value, form_data[1].value, 187 | function(resp) { 188 | if (resp.error) { 189 | $('#signin .error').html('Wrong user/password combination.'); 190 | } else { 191 | window.store.set('username', form_data[0].value); 192 | 193 | console.log(form_data); 194 | 195 | if (form_data[2]) { 196 | window.store.set('access_token', resp.access_token); 197 | window.store.set('refresh_token', resp.refresh_token); 198 | } else { 199 | window.store.remove('access_token'); 200 | window.store.remove('refresh_token'); 201 | } 202 | 203 | updateUser(); 204 | 205 | $('#signin').hide(); 206 | $('#main_content').show(); 207 | 208 | $('body').css({ 'width': '380px' }); 209 | } 210 | } 211 | ); 212 | 213 | return false; 214 | } 215 | 216 | $('#signin form.signin').bind('submit', authUser); 217 | 218 | function registerUser() { 219 | var $form = $('#signin form.signup'); 220 | var form_data = $form.serializeArray(); 221 | 222 | Minus.registerUser(form_data[0].value, form_data[1].value, form_data[2].value, 223 | function(resp) { 224 | if (!resp.success) { 225 | $('#signin .error').html(resp.username); 226 | } else { 227 | $signin_form = $('#signin form.signin'); 228 | 229 | $signin_form.find('input[name=username]').val(form_data[0].value); 230 | $signin_form.find('input[name=password]').val(form_data[1].value); 231 | 232 | authUser(); 233 | } 234 | } 235 | ); 236 | 237 | return false; 238 | } 239 | 240 | 241 | $('#signin form.signup').bind('submit', registerUser); 242 | 243 | function updateUser() { 244 | var user = window.store.get('username'); 245 | var token = window.store.get('access_token'); 246 | var skip_loader = window.store.get('last_view'); 247 | 248 | if (token && user) { 249 | Minus.setToken(token); 250 | 251 | Minus.activeUser(function(resp) { 252 | if (resp.invalid_token) { 253 | Minus.refreshToken(window.store.get('refresh_token'), 254 | function(refresh_resp) { 255 | if (refresh_resp.error) { 256 | $('body').css({ 'width': '542px' }); 257 | $('#main_content').hide(); 258 | $('#signin').show(); 259 | } else { 260 | console.log(refresh_resp); 261 | 262 | window.store.set('access_token', refresh_resp.access_token); 263 | window.store.set('refresh_token', refresh_resp.refresh_token); 264 | 265 | updateTimeline(skip_loader); 266 | } 267 | } 268 | ); 269 | } else { 270 | updateTimeline(skip_loader); 271 | } 272 | }); 273 | 274 | $('#user').attr('href','http://minus.com/'+user); 275 | } else { 276 | $('body').css({ 'width': '542px' }); 277 | $('#main_content').hide(); 278 | $('#signin').show(); 279 | } 280 | } 281 | 282 | function updateUI() { 283 | if (window.store.get('last_view')) { 284 | $('#my_galleries').html(window.store.get('last_view')); 285 | $("#galleries_container") 286 | .jScrollPane({ 287 | maintainPosition: true, 288 | verticalDragMinHeight: 87, 289 | verticalDragMaxHeight: 87 290 | }); 291 | 292 | } 293 | 294 | updateUser(); 295 | 296 | browser.tabs.getSelected(null, function(tab) { 297 | if (window.store.get('edit_image') == undefined) 298 | window.store.set('edit_image', true); 299 | 300 | $('#edit_image').attr('checked', window.store.get('edit_image')) 301 | 302 | $('#edit_image').bind('change', function(){ 303 | window.store.set('edit_image', this.checked); 304 | }); 305 | 306 | $('#header *[data-screenshot-type]').each(function(){ 307 | var hotkey = store.get('hotkey_'+$(this).data('screenshot-type')); 308 | 309 | if (hotkey) hotkey = (browser.isPlatform('mac') ? 'Cmd' : 'Ctrl') + "+Alt+" + hotkey; 310 | 311 | $(this).find('span').html(hotkey); 312 | }); 313 | 314 | if (tab.url.match('https://') || tab.url.match('chrome://') || tab.url.match("file://")) { 315 | $('#header *[data-screenshot-type=full], #header *[data-screenshot-type=region]').remove(); 316 | } 317 | 318 | if (tab.url.match('chrome://newtab') || tab.url.match('chrome://extensions')) { 319 | $('#header *[data-screenshot-type]').remove(); 320 | $('#take_screenshot').html('Not available for this page') 321 | .parent().find('.more').hide(); 322 | } 323 | }); 324 | } 325 | 326 | 327 | browser.onReady(function() { 328 | setTimeout(updateUI, 0); 329 | }); 330 | 331 | }()) 332 | -------------------------------------------------------------------------------- /data/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 | -------------------------------------------------------------------------------- /lib/ui.js: -------------------------------------------------------------------------------- 1 | var {Cc, Ci, Cu} = require("chrome"); 2 | var data = require('self').data; 3 | var windows = require('windows'); 4 | var tabs = require('tabs'); 5 | var panel = require("panel"); 6 | var xulApp = require('xul-app'); 7 | var ss = require("simple-storage"); 8 | var storage = ss.storage; 9 | var captureData = {}; 10 | var optionsPanel; 11 | var popupPanel; 12 | 13 | var mediator = Cc['@mozilla.org/appshell/window-mediator;1'] 14 | .getService(Ci.nsIWindowMediator); 15 | var AddonManager = Cu.import("resource://gre/modules/AddonManager.jsm").AddonManager; 16 | 17 | function closePanel() { 18 | optionsPanel.hide(); 19 | } 20 | 21 | function getTimeStamp() { 22 | var y, m, d, h, M, s; 23 | var time = new Date(); 24 | y = time.getFullYear(); 25 | m = time.getMonth()+1; 26 | d = time.getDate(); 27 | h = time.getHours(); 28 | M = time.getMinutes(); 29 | s = time.getSeconds(); 30 | if (m < 10) m = '0' + m; 31 | if (d < 10) d = '0' + d; 32 | if (h < 10) h = '0' + h; 33 | if (M < 10) M = '0' + M; 34 | if (s < 10) s = '0' + s; 35 | return y + '-' + m + '-' + d + ' ' + h + '-' + M + '-' + s; 36 | } 37 | 38 | function saveCanvas(data) { 39 | var format = data.format; 40 | var window = mediator.getMostRecentWindow("navigator:browser").gBrowser.contentWindow; 41 | var nsIFilePicker = Ci.nsIFilePicker; 42 | var fp = Cc["@mozilla.org/filepicker;1"].createInstance(nsIFilePicker); 43 | fp.init(window.parent, "Save Image To", nsIFilePicker.modeSave); 44 | //fp.appendFilter('image',Components.interfaces.nsIFilePicker.filterimg); 45 | //fp.defaultExtension = 'PNG'; 46 | fp.defaultString = data.title+' '+getTimeStamp()+'.'+format; 47 | fp.appendFilter(format.toUpperCase()+' Image', '*.'+format); 48 | 49 | var show = fp.show(); 50 | if (show!=nsIFilePicker.returnCancel) { 51 | var targetDir = fp.file; 52 | var file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsILocalFile); 53 | var path = targetDir.path;// + (show==nsIFilePicker.returnOK ? '.png' : ''); 54 | 55 | var regex = new RegExp('.'+format); 56 | if (!regex.test(path)) { 57 | path += '.'+format; 58 | } 59 | 60 | file.initWithPath(path); 61 | 62 | // create a data url from the canvas and then create URIs of the source and targets 63 | var io = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService); 64 | var source = io.newURI(data.dataURL, "UTF8", null); 65 | var target = io.newFileURI(file); 66 | 67 | // prepare to save the canvas data 68 | var persist = Cc["@mozilla.org/embedding/browser/nsWebBrowserPersist;1"] 69 | .createInstance(Ci.nsIWebBrowserPersist); 70 | 71 | //persist.persistFlags = Ci.nsIWebBrowserPersist.PERSIST_FLAGS_REPLACE_EXISTING_FILES; 72 | persist.persistFlags = Ci.nsIWebBrowserPersist.PERSIST_FLAGS_AUTODETECT_APPLY_CONVERSION; 73 | 74 | //var targetFile = targetDir.clone(); 75 | 76 | // displays a download dialog (remove these 3 lines for silent download) 77 | var xfer = Cc["@mozilla.org/transfer;1"].createInstance(Ci.nsITransfer); 78 | xfer.init(source, target, "", null, null, null, persist); 79 | persist.progressListener = xfer; 80 | 81 | // save the canvas data to the file 82 | persist.saveURI(source, null, null, null, null, file); 83 | } 84 | } 85 | 86 | function capture(option) { 87 | var window = mediator.getMostRecentWindow("navigator:browser").gBrowser.contentWindow; 88 | var document = window.document; 89 | var html = document.documentElement; 90 | var w, h, x, y; 91 | switch(option) { 92 | case 'visible': 93 | x = 0; 94 | y = html.scrollTop; 95 | w = html.clientWidth; 96 | h = html.clientHeight; 97 | break; 98 | case 'full': 99 | x = y = 0; 100 | w = html.scrollWidth; 101 | h = html.scrollHeight; 102 | break; 103 | } 104 | 105 | var canvas = document.createElement('canvas'); 106 | canvas.width = w; 107 | canvas.height = h; // need refinement 108 | canvas.style.display = 'none'; 109 | document.body.appendChild(canvas); 110 | 111 | var ctx = canvas.getContext("2d"); 112 | ctx.drawWindow(window, x, y, w, h, 'rgb(255, 255, 255)'); 113 | 114 | captureData = { 115 | data: canvas.toDataURL(), 116 | taburl: window.location.href, 117 | tabtitle: document.title, 118 | w: w, h:h 119 | }; 120 | 121 | if (storage.data.edit_image) { 122 | tabs.open({url: data.url('edit_image.html')}); 123 | 124 | return false; 125 | } else { 126 | return true; 127 | } 128 | } 129 | function getCaptureData() { 130 | return captureData; 131 | } 132 | 133 | function createKeySet(doc) { 134 | var keyset = doc.createElement('keyset'); 135 | var visibleKey = doc.createElement('key'); 136 | 137 | visibleKey.setAttribute('id', 'visibleKey'); 138 | visibleKey.setAttribute('modifiers', 'control shift'); 139 | visibleKey.setAttribute('key', 'V'); 140 | visibleKey.setAttribute('oncommand', 'capture(\'visible\')'); 141 | 142 | keyset.appendChild(visibleKey); 143 | return keyset; 144 | } 145 | 146 | function createMenuPopup(doc) { 147 | var menupopup = doc.createElement('menupopup'); 148 | var visibleItem = doc.createElement('menuitem'); 149 | var entireItem = doc.createElement('menuitem'); 150 | 151 | menupopup.setAttribute('class', 'minus-screenshot-menupopup'); 152 | visibleItem.setAttribute('data-option', 'visible'); 153 | entireItem.setAttribute('data-option', 'full'); 154 | visibleItem.setAttribute('class', 'menuitem-iconic'); 155 | entireItem.setAttribute('class', 'menuitem-iconic'); 156 | visibleItem.setAttribute('label', 'Capture Visible Part'); 157 | entireItem.setAttribute('label', 'Capture Full page'); 158 | //visibleItem.setAttribute('image', data.url('img/visible.png')); 159 | //entireItem.setAttribute('image', data.url('img/entire.png')); 160 | visibleItem.setAttribute('key', 'visibleKey'); 161 | 162 | var separator = doc.createElement('menuseparator'); 163 | 164 | var options = doc.createElement('menuitem'); 165 | options.setAttribute('data-option', 'options'); 166 | options.setAttribute('label', 'Options'); 167 | 168 | menupopup.appendChild(visibleItem); 169 | menupopup.appendChild(entireItem); 170 | menupopup.appendChild(separator); 171 | menupopup.appendChild(options); 172 | return menupopup; 173 | } 174 | function prepareKeys(doc, container) { 175 | //container.appendChild(createKeySet(doc)); 176 | doc.addEventListener('keyup', function(e) { 177 | //console.log(e.keyCode); 178 | }, false); 179 | } 180 | // called by addToolbarButton and addContextMenu 181 | function prepareMenu(doc, container, wrapper) { 182 | container.appendChild(wrapper); 183 | wrapper.appendChild(createMenuPopup(doc)); 184 | 185 | // maybe change to menupopup 186 | wrapper.addEventListener('mousedown', function(e) { 187 | var target = e.target; 188 | // XULElement don't have parentElement property, so we use parentNode 189 | if (/minus-screenshot-menupopup/.test(target.parentNode.className) 190 | && e.which===1) { 191 | 192 | var action = target.getAttribute('data-option'); 193 | if (action==='options') { 194 | optionsPanel.show(); 195 | } 196 | else capture(action); 197 | } 198 | }, false); 199 | } 200 | 201 | function addToolbarButton(doc) { 202 | var addonBar = doc.getElementById("nav-bar"); 203 | if (!addonBar) return; 204 | 205 | var toolbarbutton = doc.createElement("toolbarbutton"); 206 | 207 | var id = toolbarbutton.id = 'minus-screenshot-toolbarbutton'; 208 | toolbarbutton.setAttribute('type', 'panel'); 209 | toolbarbutton.setAttribute('class', 'toolbarbutton-1 chromeclass-toolbar-additional'); 210 | toolbarbutton.setAttribute('image', data.url('images/logo16.png')); 211 | toolbarbutton.setAttribute('orient', 'horizontal'); 212 | toolbarbutton.setAttribute('label', 'Minus - Share simply'); 213 | 214 | doc.defaultView.addEventListener("aftercustomization", function() { 215 | var as = doc.getElementById(id); 216 | storage.customize = { 217 | parent: as ? as.parentNode.id : null, 218 | next: as ? as.nextSibling.id : null 219 | }; 220 | }, false); 221 | 222 | //prepareKeys(doc, addonBar); 223 | //prepareMenu(doc, addonBar, toolbarbutton); 224 | 225 | addonBar.appendChild(toolbarbutton); 226 | 227 | toolbarbutton.onclick = function(evt) { 228 | popupPanel.show(toolbarbutton); 229 | } 230 | 231 | doc.getElementById("navigator-toolbox").palette.appendChild(toolbarbutton); 232 | 233 | var parent = storage.customize.parent; 234 | var next = storage.customize.next; 235 | if (parent) doc.getElementById(parent).insertItem(id, doc.getElementById(next), null, false); 236 | } 237 | 238 | function startToolbarAnimation() { 239 | var win = mediator.getMostRecentWindow("navigator:browser"); 240 | var toolbarbutton = win.document.getElementById('minus-screenshot-toolbarbutton'); 241 | 242 | toolbarbutton.setAttribute('image', data.url('images/logo16_anim.gif')); 243 | } 244 | 245 | function stopToolbarAnimation() { 246 | var win = mediator.getMostRecentWindow("navigator:browser"); 247 | var toolbarbutton = win.document.getElementById('minus-screenshot-toolbarbutton'); 248 | 249 | toolbarbutton.setAttribute('image', data.url('images/logo16.png')); 250 | } 251 | 252 | function addContextMenu(doc) { 253 | var popup = doc.getElementById('contentAreaContextMenu'); 254 | if (!popup) return; 255 | var menu = doc.createElement('menu'); 256 | 257 | menu.setAttribute('id', 'minus-screenshot-contextmenu'); 258 | menu.setAttribute('label', 'Minus'); 259 | menu.setAttribute('class', 'menu-iconic'); 260 | menu.setAttribute('image', data.url('images/logo16.png')); 261 | 262 | prepareMenu(doc, popup, menu); 263 | } 264 | 265 | function isPlatform(operationSystem){ 266 | var win = mediator.getMostRecentWindow("navigator:browser"); 267 | 268 | return win.navigator.userAgent.toLowerCase().indexOf(operationSystem) > -1; 269 | } 270 | 271 | function addShortcuts(win) { 272 | win.addEventListener('keyup', function(e) { 273 | // Send compose key like Ctrl + Alt + alphabetical-key to background. 274 | if ((e.ctrlKey && e.altKey && !isPlatform('mac') || 275 | e.metaKey && e.altKey && isPlatform('mac')) && 276 | e.which > 64 && e.which < 91) 277 | { 278 | var menu = storage.options.shortcuts; 279 | 280 | switch(String.fromCharCode(e.which)) { 281 | // why the key is lowercase afte save it? 282 | case menu.visible.key.toUpperCase(): 283 | capture('visible'); 284 | break; 285 | case menu.entire.key.toUpperCase(): 286 | capture('full'); 287 | break; 288 | } 289 | } 290 | }, false); 291 | } 292 | 293 | function addUI(win) { 294 | win = win || mediator.getMostRecentWindow("navigator:browser"); 295 | var doc = win.document; 296 | 297 | addToolbarButton(doc); 298 | addContextMenu(doc); 299 | addShortcuts(win); 300 | } 301 | function removeUI(win) { 302 | var doc = win.document; 303 | 304 | var addonBar = doc.getElementById("nav-bar"); 305 | var button = doc.getElementById("minus-screenshot-toolbarbutton"); 306 | if (button) addonBar.removeChild(button); 307 | 308 | var popup = doc.getElementById('contentAreaContextMenu'); 309 | var menu = doc.getElementById("minus-screenshot-contextmenu"); 310 | if (menu) popup.removeChild(menu); 311 | } 312 | 313 | function addAll() { 314 | var enumerator = mediator.getEnumerator(null); 315 | while(enumerator.hasMoreElements()) { 316 | addUI(enumerator.getNext()); 317 | } 318 | } 319 | function removeAll() { 320 | var enumerator = mediator.getEnumerator(null); 321 | while(enumerator.hasMoreElements()) { 322 | removeUI(enumerator.getNext()); 323 | } 324 | } 325 | 326 | function resizePopup(width, height) { 327 | if (popupPanel.isShowing) { 328 | popupPanel.resize(width, height); 329 | } else { 330 | popupPanel.width = width; 331 | popupPanel.height = height; 332 | } 333 | } 334 | 335 | function init(capture) { 336 | popupPanel = panel.Panel({ 337 | contentURL: data.url("popup.html"), 338 | width: 100, height: 100 339 | }); 340 | 341 | AddonManager.addAddonListener({ 342 | onDisabled: function(addon) { 343 | if (addon.id==='jid0-IqTRXaCOez4eRl9nE76oWp1G2iE@jetpack') { 344 | removeAll(); 345 | } 346 | } 347 | }); 348 | windows.browserWindows.on('open', function(window) { 349 | addUI(null); 350 | }); 351 | removeAll(); 352 | addAll(); 353 | 354 | optionsPanel = panel.Panel({ 355 | contentURL: data.url("options.html"), 356 | width: 700, height: 450 357 | }); 358 | } 359 | 360 | exports.init = init; 361 | exports.getCaptureData = getCaptureData; 362 | exports.capture = capture; 363 | exports.saveCanvas = saveCanvas; 364 | exports.closePanel = closePanel; 365 | exports.startToolbarAnimation = startToolbarAnimation; 366 | exports.stopToolbarAnimation = stopToolbarAnimation; 367 | exports.resizePopup = resizePopup; 368 | -------------------------------------------------------------------------------- /data/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 | text-align: center; 119 | font-weight: bold; 120 | color: #363636; 121 | font-size: 16px; 122 | } 123 | 124 | #signin form input[type=submit]:hover { 125 | color: #f19600; 126 | } 127 | 128 | #signin .signin { 129 | background: url(../images/separator.png) center right no-repeat; 130 | } 131 | 132 | #header { 133 | padding-left: 10px; 134 | position: relative; 135 | z-index: 999999; 136 | margin-top: 10px; 137 | } 138 | 139 | #header .more { 140 | width: 62px; 141 | height: 47px; 142 | 143 | position: absolute; 144 | top: 0px; 145 | right: 10px; 146 | 147 | text-align: center; 148 | font-size: 20px; 149 | 150 | background: white; 151 | 152 | 153 | background-image: url(../images/gear.png), url(../images/take_screenshot.png); 154 | background-repeat: no-repeat, repeat-x; 155 | background-position: center, top center; 156 | } 157 | 158 | #header .more.hover { 159 | text-decoration: none; 160 | cursor: pointer; 161 | opacity: 1; 162 | 163 | z-index: 99999; 164 | 165 | background: white url(../images/gear.png) center 10px no-repeat; 166 | border: 2px solid #666; 167 | border-bottom: none; 168 | 169 | width: 58px; 170 | height: 47px; 171 | 172 | box-shadow: 0 0 3px 1px #ccc; 173 | } 174 | 175 | #header .more.hover img { 176 | opacity: 1; 177 | } 178 | 179 | #header .more > div { 180 | position: absolute; 181 | 182 | top: 45px; 183 | right: -2px; 184 | 185 | width: 225px; 186 | 187 | background: white; 188 | border: 2px solid #666; 189 | 190 | font-size: 16px; 191 | text-align: left; 192 | 193 | z-index: 9999; 194 | opacity: 1; 195 | 196 | box-shadow: 0 0 3px 1px #ccc; 197 | 198 | padding-top: 8px; 199 | } 200 | 201 | #header .connector { 202 | position: absolute; 203 | right: -2px; 204 | top: -5px; 205 | height: 5px; 206 | width: 58px; 207 | background: white; 208 | border-left: 2px solid #666; 209 | border-right: 2px solid #666; 210 | } 211 | 212 | #header .more > div li { 213 | padding: 8px 10px; 214 | color: #999; 215 | font-size: 13px; 216 | } 217 | 218 | #header .more > div li:hover span, #header .more > div li:hover label { 219 | color: #f7931e; 220 | text-decoration: underline; 221 | cursor: pointer; 222 | } 223 | 224 | #header .more > div span { 225 | float: right; 226 | font-size: 12px; 227 | color: #666; 228 | font-weight: bold; 229 | } 230 | 231 | #header .more .edit_image_config { 232 | margin-top: 10px; 233 | 234 | border-top: 1px solid #ccc; 235 | line-height: 12px; 236 | } 237 | 238 | #header .more .options { 239 | cursor: pointer; 240 | font-size: 14px; 241 | } 242 | 243 | #header .more .edit_image_config input { 244 | vertical-align: middle; 245 | } 246 | 247 | #header .more .edit_image_config label { 248 | cursor: pointer; 249 | margin-left: 5px; 250 | font-size: 11px; 251 | text-transform: uppercase; 252 | vertical-align: middle; 253 | } 254 | 255 | #timeline { 256 | background: url(../images/dashboard.png); 257 | margin: 0px 10px; 258 | height: 22px; 259 | width: 361px; 260 | text-transform: uppercase; 261 | 262 | font-size: 12px; 263 | 264 | color: #999; 265 | font-weight: bold; 266 | 267 | padding-top: 7px; 268 | 269 | cursor: default; 270 | 271 | font-weight: bold; 272 | } 273 | 274 | #timeline span { 275 | margin-right: 33px; 276 | margin-left: 15px; 277 | } 278 | 279 | #timeline a { 280 | color: #999; 281 | margin-right: 16px; 282 | cursor: pointer; 283 | } 284 | 285 | #timeline a.active { 286 | color: #333; 287 | } 288 | 289 | 290 | #latest_file input { 291 | width: 210px; 292 | margin-left: 5px; 293 | } 294 | 295 | #galleries_container { 296 | margin: 0; 297 | height: auto; 298 | max-height: 380px; 299 | width: 100%; 300 | overflow-x: hidden; 301 | 302 | margin-top: 10px; 303 | } 304 | 305 | #my_galleries { 306 | margin:0; 307 | padding:0; 308 | list-style: none; 309 | 310 | width: 100%; 311 | } 312 | 313 | #my_galleries li { 314 | padding: 8px; 315 | margin-top: 5px; 316 | margin-bottom: 10px; 317 | 318 | border: 1px solid #cecece; 319 | box-shadow: 0 0 3px 1px rgba(200,200,200, 0.3); 320 | 321 | position: relative; 322 | 323 | margin-left: 10px; 324 | margin-right: 10px; 325 | 326 | width: 324px; 327 | height: 60px; 328 | 329 | background: #fff; 330 | font-weight: bold; 331 | } 332 | 333 | #my_galleries li.loader { 334 | background: url(../images/loading.gif) center no-repeat; 335 | margin-left: 30px; 336 | height: 30px; 337 | box-shadow: none; 338 | border: none; 339 | } 340 | 341 | #my_galleries li .preview { 342 | padding-right: 10px; 343 | } 344 | 345 | #my_galleries li .action { 346 | position: relative; 347 | } 348 | 349 | #my_galleries li .action img { 350 | position: absolute; 351 | top: -9px; 352 | right: -9px; 353 | } 354 | 355 | #my_galleries li .action a { 356 | cursor: pointer; 357 | } 358 | 359 | #my_galleries li .action a:hover { 360 | } 361 | 362 | #my_galleries li .creator { 363 | font-size: 12px; 364 | color: #999; 365 | cursor: default; 366 | } 367 | 368 | #my_galleries li .creator a { 369 | color: #f19600; 370 | cursor: pointer; 371 | } 372 | 373 | #my_galleries .name { 374 | max-width: 215px; 375 | display: inline-block; 376 | overflow: hidden; 377 | white-space: nowrap; 378 | text-overflow: ellipsis; 379 | color: #333; 380 | font-size: 15px; 381 | } 382 | 383 | #my_galleries .share_link { 384 | background: #eee; 385 | width: 185px; 386 | } 387 | 388 | #my_galleries .items { 389 | margin-right: 0px; 390 | font-size: 12px; 391 | font-family: Arial; 392 | color: #999; 393 | white-space: nowrap; 394 | cursor: default; 395 | } 396 | 397 | #my_galleries .items.dot { 398 | } 399 | 400 | #take_screenshot { 401 | display: block; 402 | width: 286px; 403 | 404 | cursor: pointer; 405 | 406 | font-size: 22px; 407 | font-weight: bold; 408 | 409 | color: #666; 410 | 411 | background-image: url(../images/btn_camera_gray.png), url(../images/take_screenshot.png); 412 | background-repeat: no-repeat, repeat-x; 413 | background-position: 15px 12px, top left; 414 | 415 | border: 0 !important; 416 | padding: 10px 15px; 417 | padding-left: 60px; 418 | 419 | padding-bottom: 10px; 420 | 421 | text-align: left; 422 | } 423 | 424 | #take_screenshot:hover { 425 | color: #333; 426 | 427 | background-image: url(../images/btn_camera_normal.png), url(../images/take_screenshot.png); 428 | } 429 | 430 | .loading #take_screenshot { 431 | text-indent: -99999px; 432 | background-image: url(../images/loading.gif), url(../images/take_screenshot.png); 433 | background-position: center, top center; 434 | } 435 | 436 | .loading .more { 437 | display: none; 438 | } 439 | 440 | h4 { 441 | margin: 0; 442 | padding: 0px 5px; 443 | } 444 | 445 | a.button { 446 | padding: 10px 14px; 447 | margin-right: 2px; 448 | border: 1px solid #ccc; 449 | border-radius: 2px; 450 | 451 | font-size: 20px; 452 | 453 | background: #fff; 454 | 455 | text-align: center; 456 | } 457 | 458 | a.button:hover { 459 | text-decoration: none; 460 | 461 | background: #eee; 462 | 463 | color: #333; 464 | } 465 | 466 | .center { 467 | text-align: center; 468 | } 469 | 470 | 471 | #footer { 472 | clear: both; 473 | height: 25px; 474 | margin-top: 5px; 475 | padding-top: 6px; 476 | padding-bottom: 9px; 477 | margin-left: 10px; 478 | 479 | position: relative; 480 | 481 | background: url(../images/bottom.png) top left no-repeat; 482 | } 483 | 484 | #footer * { 485 | float: left; 486 | } 487 | 488 | #footer img { 489 | vertical-align: middle; 490 | margin-left: 10px; 491 | } 492 | 493 | #footer a.minus_link { 494 | position: absolute; 495 | bottom: 9px; 496 | right: 60px; 497 | width: 80px; 498 | font-size: 13px; 499 | } 500 | 501 | #footer .options { 502 | font-size: 12px; 503 | font-weight: bold; 504 | color: #000; 505 | opacity: 0.7; 506 | margin-left: 10px; 507 | } 508 | 509 | #user, #signout { 510 | font-size: 11px; 511 | font-weight: bold; 512 | color: #999; 513 | margin-right: 18px; 514 | float: right; 515 | padding-top: 3px; 516 | 517 | text-transform: uppercase; 518 | } 519 | 520 | #user { 521 | text-align: left; 522 | margin-left: 80px; 523 | } 524 | 525 | #user:hover, #signout:hover { 526 | color: #333; 527 | text-decoration: none; 528 | } 529 | 530 | #signout { 531 | position: absolute; 532 | right: 5px; 533 | bottom: 10px; 534 | font-size: 12px; 535 | font-weight: normal; 536 | } 537 | 538 | #loader { 539 | position: absolute; 540 | top: 0px; 541 | left: 0px; 542 | height: 100%; 543 | width: 100%; 544 | background: rgba(200,200,200, 0.4); 545 | font-size: 16px; 546 | font-family: verdana, sans-serif; 547 | } 548 | 549 | #loader div { 550 | margin-top: 25%; 551 | background: url(../images/ajax-loader.gif) bottom center no-repeat; 552 | margin-left: auto; 553 | margin-right: auto; 554 | 555 | width: 200px; 556 | height: 20px; 557 | text-align: center; 558 | } 559 | 560 | /************* Scrollbar ***************/ 561 | .jspVerticalBar 562 | { 563 | right: 6px; 564 | border-radius: 3px; 565 | background-color: #cbcbcd; 566 | } 567 | 568 | .jspDrag { 569 | background: url(../images/scroll.png) no-repeat; 570 | width: 15px; 571 | height: 87px; 572 | 573 | left: -3px; 574 | } 575 | 576 | /********** Opera css ***********/ 577 | 578 | .opera #take_screenshot { 579 | display: none; 580 | } 581 | 582 | .opera #header span { 583 | display: none; 584 | } 585 | 586 | .opera #header:after { 587 | content: ""; 588 | } 589 | 590 | 591 | /********** Firefox css *********/ 592 | .firefox #main_content { 593 | padding-bottom: 10px; 594 | } 595 | 596 | .firefox #header li[data-screenshot-type='region'] { 597 | display: none; 598 | } 599 | 600 | -------------------------------------------------------------------------------- /data/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 */ -------------------------------------------------------------------------------- /data/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 10000000) { 276 | console.error("File too large"); 277 | 278 | callback({ error: "file_size_error", message: "Maximum allowed file size is 10 mb." }); 279 | } else { 280 | if (navigator.userAgent.match('Firefox') != undefined) { 281 | var bData = getImageFromURL(url); 282 | Minus.uploadItem(editor_id, filename, mime, bData, callback); 283 | } else { 284 | var data = new Ajax(url, { 285 | mime_type: 'text/plain; charset=x-user-defined', 286 | onSuccess: function() { 287 | Minus.uploadItem(editor_id, filename, mime, data.responseText, callback, progress); 288 | } 289 | }); 290 | } 291 | } 292 | }, 293 | 294 | onError: function() { 295 | callback({ error: "file_download_error", message: "Can't download file" }); 296 | } 297 | }); 298 | } 299 | 300 | Minus.timeline = function(username, type, page, callback) { 301 | if (!page) 302 | page = 1; 303 | 304 | this.callMethod('users/'+username+'/folders', { 305 | params: { page: page }, 306 | onSuccess: function(resp) { 307 | for (var i=0; i 2 | 3 | 4 | 5 | 6 | 7 | 8 | 194 | 195 | 196 |
    197 |
    198 |
    199 | 200 | 201 | 217 | 218 | Loading editor... 219 |
    220 |
    221 |
    222 |
    223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 340 | 341 | 416 | 417 | 418 | 428 | 429 | 430 | -------------------------------------------------------------------------------- /data/js/background.js: -------------------------------------------------------------------------------- 1 | (function(){ 2 | function getScrollbarWidth() { 3 | var inner = document.createElement('p'); 4 | inner.style.width = "100%"; 5 | inner.style.height = "200px"; 6 | 7 | var outer = document.createElement('div'); 8 | outer.style.position = "absolute"; 9 | outer.style.top = "0px"; 10 | outer.style.left = "0px"; 11 | outer.style.visibility = "hidden"; 12 | outer.style.width = "200px"; 13 | outer.style.height = "150px"; 14 | outer.style.overflow = "hidden"; 15 | outer.appendChild (inner); 16 | 17 | document.body.appendChild (outer); 18 | var w1 = inner.offsetWidth; 19 | outer.style.overflow = 'scroll'; 20 | var w2 = inner.offsetWidth; 21 | if (w1 == w2) w2 = outer.clientWidth; 22 | 23 | document.body.removeChild (outer); 24 | 25 | return (w1 - w2); 26 | } 27 | 28 | var canvas = $('').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 | // Gif file editing is forbided 55 | if (store.get('edit_image') && !data.srcUrl.match("\.gif")) { 56 | window.latest_screenshot = data.srcUrl; 57 | browser.tabs.create({ url: browser.extension.getURL('/edit_image.html?title='+data.srcUrl) }); 58 | } else { 59 | uploadScreenshot(data.srcUrl, '', data.srcUrl); 60 | } 61 | } 62 | 63 | function captureFromMenu(captureType) { 64 | listener({ method: 'takeScreenshot', captureType: captureType }); 65 | } 66 | 67 | function initContextMenu() { 68 | if (browser.isChrome || browser.isFirefox) { 69 | browser.contextMenus.create({ 70 | "title": "Upload to min.us", 71 | "onclick" : createGalleryClick, 72 | "contexts":["image"] 73 | }); 74 | 75 | browser.contextMenus.create({ 76 | "title": "Capture Visible Part of Page", 77 | "onclick" : function(){ captureFromMenu('visible') } 78 | }); 79 | 80 | browser.contextMenus.create({ 81 | "title": "Capture Selected Area", 82 | "onclick" : function(){ captureFromMenu('region') }, 83 | "documentUrlPatterns": ["http://*/*"] 84 | }); 85 | 86 | browser.contextMenus.create({ 87 | "title": "Capture Entire Page", 88 | "onclick" : function(){ captureFromMenu('full') }, 89 | "documentUrlPatterns": ["http://*/*"] 90 | }); 91 | 92 | 93 | } else if(browser.isSafari) { 94 | function handleContextMenu(event) { 95 | if (event.userInfo.nodeName === "IMG") { 96 | event.contextMenu.appendContextMenuItem("context_menu_1", "Upload to Minus"); 97 | } 98 | } 99 | 100 | safari.application.addEventListener("contextmenu", handleContextMenu, false); 101 | 102 | safari.application.addEventListener("command", function(event) { 103 | if (event.command == "context_menu_1") { 104 | createGalleryClick(event.userInfo); 105 | } 106 | }, false); 107 | } 108 | } 109 | 110 | function uploadItem(binaryData, gallery_id, title, onProgress){ 111 | anim.start(); 112 | 113 | Minus.uploadItem(gallery_id, title.slice(0,50)+".png", "image/png", binaryData, 114 | function(resp){ 115 | anim.stop(); 116 | 117 | browser.toolbarItem.setText(''); 118 | 119 | console.log('resp'); 120 | 121 | if (!resp.error) 122 | browser.tabs.create({ url: "http://minus.com/m"+gallery_id }); 123 | 124 | browser.postMessage({ method: "uploadComplete" }); 125 | }, 126 | 127 | onProgress 128 | ); 129 | } 130 | 131 | function uploadScreenshot(base64Data, gallery_id, title) { 132 | Minus.setUser(window.store.get('username')); 133 | Minus.setToken(window.store.get('access_token')); 134 | 135 | var onProgress = function(progress) { 136 | console.log('updating progress'); 137 | 138 | var percent = parseInt(progress)+'%'; 139 | browser.toolbarItem.setText(percent); 140 | 141 | browser.postMessage({ method:"uploadProgress", progress: progress }); 142 | } 143 | 144 | function upload() { 145 | var binaryData = atob(base64Data.replace(/^data\:image\/png\;base64\,/,'')); 146 | 147 | if (!gallery_id) { 148 | Minus.createGallery(null, function(gallery) { 149 | uploadItem(binaryData, gallery.id, title, onProgress); 150 | }); 151 | } else { 152 | uploadItem(binaryData, gallery_id, title, onProgress); 153 | } 154 | } 155 | 156 | if (base64Data.slice(0,4) == 'data') { 157 | upload(); 158 | } else { 159 | anim.start(); 160 | 161 | Minus.createGallery(null, function(gallery) { 162 | Minus.uploadItemFromURL(base64Data, gallery.id, function(resp){ 163 | anim.stop(); 164 | 165 | browser.toolbarItem.setText(''); 166 | 167 | if (!resp.error) 168 | browser.tabs.create({ url: "http://minus.com/m"+gallery.id }); 169 | 170 | browser.postMessage({ method: "uploadComplete" }); 171 | }, onProgress); 172 | }); 173 | } 174 | } 175 | 176 | function captureVisible(callback) { 177 | browser.tabs.captureVisibleTab(null, {format: 'png'}, function(dataUrl) { 178 | callback(dataUrl); 179 | }); 180 | } 181 | 182 | function concatImages(image_data_array, callback) { 183 | if (!$.isArray(image_data_array)) 184 | return false; 185 | 186 | var images = [], 187 | image, 188 | loaded_images = 0, 189 | total_height = 0, 190 | total_width = 0, 191 | concated_height = 0; 192 | 193 | var canvas = $('').appendTo(document.body); 194 | 195 | var imageLoaded = function() { 196 | total_width = this.naturalWidth; 197 | total_height = total_height + this.naturalHeight; 198 | 199 | loaded_images += 1; 200 | 201 | // All images loaded 202 | if (loaded_images == image_data_array.length) { 203 | canvas[0].width = total_width; 204 | canvas[0].height = total_height; 205 | ctx = canvas[0].getContext('2d'); 206 | 207 | for (var i=0; i').appendTo(document.body); 234 | ctx = canvas[0].getContext('2d'); 235 | 236 | var image = new Image; 237 | image.src = imageData; 238 | image.onload = function(){ 239 | canvas[0].width = image.naturalWidth; 240 | canvas[0].height = image.naturalHeight - heightFix; 241 | 242 | ctx.drawImage(image, 0, -heightFix); 243 | callback(canvas[0].toDataURL()); 244 | 245 | canvas.remove(); 246 | } 247 | } 248 | 249 | function cropImage(bounds, imageData, callback) { 250 | var canvas = $('').appendTo(document.body); 251 | ctx = canvas[0].getContext('2d'); 252 | 253 | var image = new Image; 254 | image.src = imageData; 255 | image.onload = function(){ 256 | canvas[0].width = bounds.width; 257 | canvas[0].height = bounds.height; 258 | 259 | ctx.drawImage(image, bounds.left, bounds.top, bounds.width, bounds.height, 0, 0, bounds.width, bounds.height); 260 | callback(canvas[0].toDataURL()); 261 | 262 | canvas.remove() 263 | } 264 | } 265 | 266 | function updateSettings(receiver) { 267 | if (store.get('icon_type') == 'bw') { 268 | browser.toolbarItem.setIcon({ path: "images/logo_small_bw.png" }); 269 | } else { 270 | browser.toolbarItem.setIcon({ path: "images/logo_small.png" }); 271 | } 272 | 273 | var settings = {}; 274 | settings[store.get('hotkey_visible')||'V'] = 'visible'; 275 | settings[store.get('hotkey_region')||'R'] = 'region'; 276 | settings[store.get('hotkey_full')||'H'] = 'full'; 277 | 278 | console.log(receiver); 279 | 280 | browser.postMessage({ method: 'updateSettings', settings: settings }, receiver); 281 | } 282 | 283 | var listener = function(msg, sender, sendResponse) { 284 | console.log('Received message', msg); 285 | 286 | switch (msg.method) { 287 | case 'takeScreenshot': 288 | anim.start(); 289 | 290 | browser.tabs.getSelected(null, function(tab) { 291 | switch (msg.captureType) { 292 | case 'visible': 293 | captureVisible(function(dataUrl){ 294 | removeVScrollbar(dataUrl, function(imageData){ 295 | window.latest_screenshot = imageData; 296 | 297 | if (store.get('edit_image')) { 298 | anim.stop(); 299 | 300 | browser.postMessage({ method: "screenshotComplete" }); 301 | browser.tabs.create({ url: browser.extension.getURL('/edit_image.html?title='+encodeURIComponent(tab.title)) }); 302 | } else { 303 | uploadScreenshot(imageData, '', tab.title) 304 | } 305 | }); 306 | }); 307 | 308 | break; 309 | case 'full': 310 | window.latest_screenshot = []; 311 | browser.postMessage({ method: "scroll", initial: true }, tab); 312 | break; 313 | 314 | case 'scroll': 315 | captureVisible(function(imageData){ 316 | if (msg.finished) { 317 | concatImages(window.latest_screenshot, function(image){ 318 | removeVScrollbar(image, function(imageData){ 319 | window.latest_screenshot = imageData; 320 | 321 | if (store.get('edit_image')) { 322 | anim.stop(); 323 | 324 | browser.tabs.create({ url: browser.extension.getURL('/edit_image.html?title='+tab.title) }); 325 | browser.postMessage({ method: "screenshotComplete" }); 326 | } else { 327 | uploadScreenshot(imageData, '', tab.title) 328 | } 329 | }); 330 | }); 331 | } else { 332 | cropHeight(msg.heightFix, imageData, function(image){ 333 | window.latest_screenshot.push(image); 334 | 335 | browser.postMessage({ method: "scroll" }, tab); 336 | }); 337 | } 338 | }); 339 | break; 340 | 341 | case 'region': 342 | anim.stop(); 343 | 344 | if (msg.finished) { 345 | captureVisible(function(imageData) { 346 | cropImage(msg.bounds, imageData, function(image){ 347 | window.latest_screenshot = image; 348 | 349 | if (store.get('edit_image')) { 350 | browser.tabs.create({ url: browser.extension.getURL('/edit_image.html?title='+tab.title) }); 351 | browser.postMessage({ method: "screenshotComplete" }); 352 | } else { 353 | uploadScreenshot(image, '', tab.title) 354 | } 355 | }); 356 | }); 357 | } else { 358 | browser.postMessage({ method: 'region' }, tab); 359 | } 360 | break; 361 | } 362 | }); 363 | break; 364 | 365 | case 'uploadScreenshot': 366 | uploadScreenshot(msg.imageData, msg.gallery, msg.title); 367 | 368 | break; 369 | 370 | case 'setUsername': 371 | store.set('username', msg.username); 372 | 373 | browser.postMessage({ method: 'setUsername', username: msg.username }); 374 | 375 | break; 376 | 377 | case 'updateSettings': 378 | updateSettings(msg.global ? undefined : sender.tab); 379 | 380 | break; 381 | 382 | case 'timeline': 383 | Minus.timeline(msg.username, msg.timeline, msg.page, 384 | function(resp) { 385 | sendResponse(resp); 386 | } 387 | ); 388 | 389 | break; 390 | 391 | case '_ajax': 392 | var xhr; 393 | var send = function() { 394 | console.log('sending response', sendResponse); 395 | 396 | sendResponse({ 397 | status: xhr.status, 398 | responseText: xhr.responseText, 399 | responseHeaders: xhr.getAllResponseHeaders() 400 | }); 401 | }; 402 | 403 | xhr = new Minus.Ajax(msg.httpOptions.url, { 404 | method: msg.httpOptions.method, 405 | headers: msg.httpOptions.headers, 406 | binaryData: msg.httpOptions.binary ? msg.httpOptions.data : null, 407 | params: msg.httpOptions.binary ? null : msg.httpOptions.data, 408 | 409 | onSuccess: send, 410 | onError: send 411 | }); 412 | } 413 | } 414 | 415 | browser.addMessageListener(listener); 416 | 417 | function executeInExistingTabs(){ 418 | chrome.windows.getAll(null, function(wins) { 419 | for (var j = 0; j < wins.length; ++j) { 420 | chrome.tabs.getAllInWindow(wins[j].id, function(tabs) { 421 | for (var i = 0; i < tabs.length; ++i) { 422 | if (tabs[i].url.match('chrome://') || tabs[i].url.match('chrome-devtools://')) 423 | continue; 424 | 425 | try { 426 | chrome.tabs.executeScript(tabs[i].id, { file: 'js/jquery.min.js' }); 427 | chrome.tabs.executeScript(tabs[i].id, { file: 'js/browser_api.js' }); 428 | chrome.tabs.executeScript(tabs[i].id, { file: 'js/content_script.js' }); 429 | 430 | chrome.tabs.insertCSS(tabs[i].id, { file: 'css/reset-context-min.css' }); 431 | chrome.tabs.insertCSS(tabs[i].id, { file: 'css/page.css' }); 432 | } catch(e) {} 433 | } 434 | }); 435 | } 436 | }); 437 | } 438 | 439 | browser.onReady(function(){ 440 | initContextMenu(); 441 | executeInExistingTabs(); 442 | updateSettings(); 443 | }); 444 | 445 | }()); 446 | -------------------------------------------------------------------------------- /data/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