├── src ├── angularsendfeedback.html ├── icons.png ├── angularModule.js ├── angular-send-feedback.less └── angularSendFeedback.js ├── dist ├── icons.png ├── angular-send-feedback.min.css ├── angular-send-feedback.less ├── angular-send-feedback.css ├── angular-send-feedback.min.js └── angular-send-feedback.js ├── .gitignore ├── bower.json ├── CHANGELOG.md ├── LICENSE ├── package.json ├── test └── angularNumberIncrementorSpec.js ├── karma.conf.js ├── Gruntfile.js └── README.md /src/angularsendfeedback.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /dist/icons.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jacobscarter/angular-feedback/HEAD/dist/icons.png -------------------------------------------------------------------------------- /src/icons.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jacobscarter/angular-feedback/HEAD/src/icons.png -------------------------------------------------------------------------------- /src/angularModule.js: -------------------------------------------------------------------------------- 1 | angular.module('angular-send-feedback', ['templates-angularsendfeedback']); 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .AppleDouble 3 | .LSOverride 4 | 5 | # Icon must end with two \r 6 | Icon 7 | 8 | 9 | # Thumbnails 10 | ._* 11 | 12 | # Files that might appear on external disk 13 | .Spotlight-V100 14 | .Trashes 15 | 16 | # Directories potentially created on remote AFP share 17 | .AppleDB 18 | .AppleDesktop 19 | Network Trash Folder 20 | Temporary Items 21 | .apdisk 22 | 23 | node_modules 24 | lib 25 | angular-send-feedback.tpls.js 26 | bower_components 27 | .idea -------------------------------------------------------------------------------- /bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "angular-send-feedback", 3 | "version": "1.2.1", 4 | "main": [ 5 | "./dist/angular-send-feedback.js", 6 | "./dist/angular-send-feedback.css" 7 | ], 8 | "description": "Angular feedback directive similar to Google Feedback", 9 | "repository": { 10 | "type": "git", 11 | "url": "git://github.com/jacobscarter/angular-feedback.git" 12 | }, 13 | "dependencies": { 14 | "angular": "*", 15 | "jquery": "*", 16 | "html2canvas": "*" 17 | }, 18 | "ignore": [ 19 | "node_modules", 20 | "components", 21 | "lib" 22 | ] 23 | } -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | 2 | # 1.2.0 (2016-06-28) 3 | 4 | 5 | ## Updates 6 | 7 | - **Corrected issue with JSON being URLEncoded. 8 | - **Added option to send timestamp along with request. 9 | 10 | 11 | # 1.1.0 (2015-04-25) 12 | 13 | 14 | ## Updates 15 | 16 | - **added content type to ajax call** Added content type of 'application/json'. 17 | - **moved button html to property in settings.tpl** 18 | - **added CSS file to main** CSS file now in bower main property. 19 | - **published to npm** `npm install angular-send-feedback`. 20 | - **ajaxURL optionally a function** ajaxURL property can be either a string or a function. -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Jacob Carter 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "angular-send-feedback", 3 | "description": "Angular feedback directive similar to Google Feedback", 4 | "version": "1.2.1", 5 | "filename": "angular-send-feedback.min.js", 6 | "main": "./dist/angular-send-feedback.min.js", 7 | "homepage": "https://github.com/jacobscarter/angular-feedback", 8 | "author": "Jacob Carter ", 9 | "repository": { 10 | "type": "git", 11 | "url": "git://github.com/jacobscarter/angular-feedback.git" 12 | }, 13 | "keywords": [ 14 | "angular", 15 | "ui", 16 | "feedback", 17 | "google-feedback" 18 | ], 19 | "maintainers": [ 20 | { 21 | "name": "Jacob Carter", 22 | "website": "http://strangemilk.com/" 23 | } 24 | ], 25 | "dependencies": {}, 26 | "devDependencies": { 27 | "grunt": "~0.4.1", 28 | "grunt-bower": "*", 29 | "grunt-bower-task": "*", 30 | "grunt-bump": "0.0.6", 31 | "grunt-contrib-clean": "~0.4.1", 32 | "grunt-contrib-concat": "~0.3.0", 33 | "grunt-contrib-copy": "~0.4.1", 34 | "grunt-contrib-uglify": "~0.2.0", 35 | "grunt-conventional-changelog": "~0.1.1", 36 | "grunt-html2js": "~0.1.3", 37 | "grunt-karma": "~0.8", 38 | "grunt-recess": "~0.3.0", 39 | "grunt-zip": "*", 40 | "jasmine-core": "^2.1.3", 41 | "karma-chrome-launcher": "^0.1.7", 42 | "karma-jasmine": "^0.3.2", 43 | "karma-phantomjs-launcher": "^0.1.4" 44 | }, 45 | "license": "MIT" 46 | } -------------------------------------------------------------------------------- /test/angularNumberIncrementorSpec.js: -------------------------------------------------------------------------------- 1 | describe('AngularNumberIncrementor', function() { 2 | var $compile, $rootScope; 3 | 4 | beforeEach(module('angular-number-incrementor')); 5 | 6 | 7 | beforeEach(inject(function(_$compile_, _$rootScope_) { 8 | $compile = _$compile_; 9 | $rootScope = _$rootScope_; 10 | })); 11 | 12 | function createView(scope) { 13 | scope.increase = function(){ 14 | scope.spinnerValue++; 15 | }; 16 | 17 | scope.decrease = function(){ 18 | scope.spinnerValue--; 19 | }; 20 | var element = angular.element(''); 21 | var elementCompiled = $compile(element)(scope); 22 | $rootScope.$digest(); 23 | return elementCompiled; 24 | } 25 | 26 | it("number should increase by one", function() { 27 | var scope = $rootScope.$new(); 28 | var view = createView(scope); 29 | scope.spinnerValue = 0; 30 | scope.increase(); 31 | $rootScope.$digest(); 32 | expect(scope.spinnerValue).toEqual(1); 33 | }); 34 | 35 | it("number should decrease by one", function() { 36 | var scope = $rootScope.$new(); 37 | var view = createView(scope); 38 | scope.spinnerValue = 5; 39 | scope.decrease(); 40 | $rootScope.$digest(); 41 | expect(scope.spinnerValue).toEqual(4); 42 | }); 43 | 44 | 45 | 46 | }); -------------------------------------------------------------------------------- /karma.conf.js: -------------------------------------------------------------------------------- 1 | // Karma configuration 2 | // Generated on Fri Aug 09 2013 14:14:35 GMT-0500 (CDT) 3 | 4 | module.exports = function(config) { 5 | config.set({ 6 | 7 | // base path, that will be used to resolve files and exclude 8 | basePath: '', 9 | 10 | frameworks: ["jasmine"], 11 | 12 | // list of files / patterns to load in the browser 13 | files: [ 14 | 'https://ajax.googleapis.com/ajax/libs/angularjs/1.3.0-beta.6/angular.js', 15 | 'https://ajax.googleapis.com/ajax/libs/angularjs/1.3.0-beta.6/angular-mocks.js', 16 | 'dist/*.js', 17 | 'test/*.js' 18 | ], 19 | 20 | 21 | // list of files to exclude 22 | exclude: [ 23 | 24 | ], 25 | 26 | 27 | // test results reporter to use 28 | // possible values: 'dots', 'progress', 'junit' 29 | reporters: ['progress'], 30 | 31 | 32 | // web server port 33 | port: 9878, 34 | 35 | 36 | // cli runner port 37 | runnerPort: 9100, 38 | 39 | 40 | // enable / disable colors in the output (reporters and logs) 41 | colors: true, 42 | 43 | 44 | // level of logging 45 | // possible values: LOG_DISABLE || LOG_ERROR || LOG_WARN || LOG_INFO || LOG_DEBUG 46 | logLevel: config.LOG_INFO, 47 | 48 | 49 | // enable / disable watching file and executing tests whenever any file changes 50 | autoWatch: true, 51 | 52 | 53 | // Start these browsers, currently available: 54 | // - Chrome 55 | // - ChromeCanary 56 | // - Firefox 57 | // - Opera 58 | // - Safari (only Mac) 59 | // - PhantomJS 60 | // - IE (only Windows) 61 | browsers: ['PhantomJS', 'Chrome'], 62 | 63 | 64 | // If browser does not capture in given timeout [ms], kill it 65 | captureTimeout: 60000, 66 | 67 | 68 | // Continuous Integration mode 69 | // if true, it capture browsers, run tests and exit 70 | singleRun: false 71 | 72 | }); 73 | }; 74 | -------------------------------------------------------------------------------- /Gruntfile.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = function(grunt) { 4 | 5 | // Project configuration. 6 | grunt.initConfig({ 7 | pkg: grunt.file.readJSON('package.json'), 8 | meta: { 9 | banner: [ 10 | '/**', 11 | ' * <%= pkg.description %>', 12 | ' * @version v<%= pkg.version %> - <%= grunt.template.today("yyyy-mm-dd") %>' + 13 | ' * @link <%= pkg.homepage %>', 14 | ' * @author <%= pkg.author %>', 15 | ' * @license MIT License, http://www.opensource.org/licenses/MIT', 16 | ' */\n' 17 | ].join('\n') 18 | }, 19 | dirs: { 20 | dest: 'dist' 21 | }, 22 | clean: [ 23 | '<%= dirs.dest %>' 24 | ], 25 | concat: { 26 | options: { 27 | banner: '<%= meta.banner %>' 28 | }, 29 | dist: { 30 | src: ['src/*.js'], 31 | dest: '<%= dirs.dest %>/<%= pkg.name %>.js' 32 | } 33 | }, 34 | recess: { 35 | build: { 36 | src: [ 'src/angular-send-feedback.less' ], 37 | dest: '<%= dirs.dest %>/<%= pkg.name %>.css', 38 | options: { 39 | compile: true, 40 | compress: false, 41 | noUnderscores: false, 42 | noIDs: false, 43 | zeroUnits: false 44 | } 45 | }, 46 | compile: { 47 | src: [ 'src/angular-send-feedback.less' ], 48 | dest: '<%= dirs.dest %>/<%= pkg.name %>.min.css', 49 | options: { 50 | compile: true, 51 | compress: true, 52 | noUnderscores: false, 53 | noIDs: false, 54 | zeroUnits: false 55 | } 56 | } 57 | }, 58 | copy: { 59 | less_files: { 60 | files: [ 61 | { 62 | src: [ 'src/angular-send-feedback.less' ], 63 | dest: '<%= dirs.dest %>', 64 | cwd: '.', 65 | expand: true, 66 | flatten: true 67 | } 68 | ] 69 | }, 70 | icons: { 71 | files: [ 72 | { 73 | src: ['src/icons.png'], 74 | dest: '<%= dirs.dest %>', 75 | cwd: '.', 76 | expand: true, 77 | flatten: true 78 | } 79 | ] 80 | } 81 | }, 82 | bowerInstall: { 83 | install: { 84 | } 85 | }, 86 | html2js: { 87 | angularsendfeedback: { 88 | options: { 89 | base: 'src' 90 | }, 91 | src: [ 'src/*.html' ], 92 | dest: 'src/<%= pkg.name %>.tpls.js' 93 | }, 94 | }, 95 | uglify: { 96 | options: { 97 | banner: '<%= meta.banner %>' 98 | }, 99 | dist: { 100 | src: ['<%= concat.dist.dest %>'], 101 | dest: '<%= dirs.dest %>/<%= pkg.name %>.min.js' 102 | } 103 | }, 104 | karma: { 105 | options: { 106 | configFile: 'karma.conf.js' 107 | }, 108 | build: { 109 | singleRun: true, 110 | autoWatch: false 111 | }, 112 | dev: { 113 | autoWatch: true 114 | } 115 | }, 116 | changelog: { 117 | options: { 118 | dest: 'CHANGELOG.md' 119 | } 120 | } 121 | }); 122 | 123 | // Load the plugin that provides the "concat" task. 124 | grunt.loadNpmTasks('grunt-contrib-concat'); 125 | 126 | // Load the plugin that provides the "uglify" task. 127 | grunt.loadNpmTasks('grunt-contrib-uglify'); 128 | 129 | grunt.loadNpmTasks('grunt-bower-task'); 130 | 131 | grunt.renameTask("bower", "bowerInstall"); 132 | 133 | grunt.loadNpmTasks('grunt-karma'); 134 | grunt.loadNpmTasks('grunt-karma'); 135 | 136 | grunt.loadNpmTasks('grunt-conventional-changelog'); 137 | 138 | grunt.loadNpmTasks('grunt-recess'); 139 | grunt.loadNpmTasks('grunt-contrib-clean'); 140 | grunt.loadNpmTasks('grunt-contrib-copy'); 141 | grunt.loadNpmTasks('grunt-html2js'); 142 | 143 | 144 | // Default task. 145 | grunt.registerTask('default', ['build']); 146 | 147 | // Build task. 148 | grunt.registerTask('build', [ 149 | 'clean', 150 | 'bowerInstall', 151 | 'copy', 152 | 'recess', 153 | 'html2js', 154 | 'concat', 155 | 'uglify' 156 | //'karma:build' 157 | ]); 158 | 159 | grunt.registerTask('test', ['build']); 160 | 161 | 162 | // Provides the "bump" task. 163 | grunt.registerTask('bump', 'Increment version number', function() { 164 | var versionType = grunt.option('type'); 165 | function bumpVersion(version, versionType) { 166 | var type = {patch: 2, minor: 1, major: 0}, 167 | parts = version.split('.'), 168 | idx = type[versionType || 'patch']; 169 | parts[idx] = parseInt(parts[idx], 10) + 1; 170 | while(++idx < parts.length) { parts[idx] = 0; } 171 | return parts.join('.'); 172 | } 173 | var version; 174 | function updateFile(file) { 175 | var json = grunt.file.readJSON(file); 176 | version = json.version = bumpVersion(json.version, versionType || 'patch'); 177 | grunt.file.write(file, JSON.stringify(json, null, ' ')); 178 | } 179 | updateFile('package.json'); 180 | updateFile('bower.json'); 181 | grunt.log.ok('Version bumped to ' + version); 182 | }); 183 | 184 | }; 185 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # angular-feedback 2 | 3 | Feedback directive similar to Google Feedback 4 | 5 | This directive was built using [ivoviz's](http://github.com/ivoviz) feedback repo. 6 | 7 | ## Demo 8 | 9 | [http://jacobscarter.github.io/angular-feedback/](http://jacobscarter.github.io/angular-feedback/) 10 | 11 | ## Install 12 | 13 | `bower install angular-send-feedback` 14 | 15 | ## Dependencies 16 | 17 | * jQuery 18 | * html2canvas 19 | 20 | ## Use 21 | 22 | Add as a dependency to your application: 23 | 24 | `angular.module('myApp', ['angular-send-feedback']);` 25 | 26 | Add directive to your HTML: 27 | 28 | `` 29 | 30 | The options attribute is connected to a `$scope` value in your controller, you can use this object to change/modify any of the options listed below. 31 | 32 | ## Post Data 33 | 34 | The information from the client will be sent through ajax post request. The information is in JSON format. 35 | 36 | * `post.browser` - Browser information. 37 | * `post.url` - The page URL. 38 | * `post.note` - Description of the feedback. 39 | * `post.img` - The screenshot of the feedback. - **base64 encoded data URI!** 40 | * `post.html` - The structure of the page. 41 | * `post.timestamp` - Timestamp create when request is sent. 42 | 43 | Sample Request Body 44 | ``` 45 | { 46 | "feedback": { 47 | "browser": { 48 | "appCodeName": "Mozilla", 49 | "appName": "Netscape", 50 | "appVersion": "5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.110 Safari/537.36", 51 | "cookieEnabled": true, 52 | "onLine": true, 53 | "platform": "Win32", 54 | "userAgent": "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.110 Safari/537.36", 55 | "plugins": [ 56 | "Shockwave Flash", 57 | "Widevine Content Decryption Module", 58 | "Chrome PDF Viewer", 59 | "Native Client", 60 | "Chrome PDF Viewer" 61 | ] 62 | }, 63 | "html": "..." 64 | "url": "http://localhost:3000/", 65 | "timestamp": 1467129480643, 66 | "img": "data:image/png;base64,...", 67 | "note": "test" 68 | } 69 | } 70 | ``` 71 | 72 | ## Options 73 | 74 | ### ajaxURL (String) 75 | 76 | The URL where the plugin will post the screenshot and additional informations. (JSON datatype) 77 | 78 | `Default: ''` 79 | 80 | ### postTimeStamp (Boolean) 81 | 82 | Whether you want a timestamp sent in the form of number of milliseconds since 1 January 1970 00:00:00 UTC. 83 | 84 | `Default: true` 85 | 86 | ### postBrowserInfo (Boolean) 87 | 88 | Whether you want your client to post their browser information (such as useragent, plugins used, etc.) 89 | 90 | `Default: true` 91 | 92 | ### postHTML (Boolean) 93 | 94 | Whether you want your client to post the page's HTML structure. 95 | 96 | `Default: true` 97 | 98 | ### postURL (Boolean) 99 | 100 | Whether you want your client to post the URL of the page. 101 | 102 | `Default: true` 103 | 104 | ### proxy (String) 105 | 106 | Url to the proxy which is to be used for loading cross-origin images. If left empty, cross-origin images won't be loaded. 107 | 108 | `Default: ''` 109 | 110 | ### letterRendering (Boolean) 111 | 112 | Whether to render each letter seperately. Necessary if letter-spacing is used. 113 | 114 | `Default: false` 115 | 116 | ### initButtonText (String / HTML) 117 | 118 | The default button text. 119 | 120 | `Default: Send feedback` 121 | 122 | ### strokeStyle (String / HEX color) 123 | 124 | The color of the highlight border. You can use values either like 'black', 'red', etc. or HEX codes like '#adadad'. 125 | 126 | `Default: black` 127 | 128 | ### shadowColor (String / HEX color) 129 | 130 | The color of the shadow. 131 | 132 | `Default: black` 133 | 134 | ### shadowOffsetX / shadowOffsetY (Integer) 135 | 136 | Sets the horizontal / vertical distance of the shadow from the shape. 137 | 138 | `Default: 1` 139 | 140 | ### shadowBlur (Integer) 141 | 142 | The blur level for the shadow. 143 | 144 | `Default: black` 145 | 146 | ### lineJoin (String) 147 | 148 | Sets the type of corner created, when two lines meet. 149 | 150 | `Default: bevel` 151 | 152 | ### lineWidth (Integer) 153 | 154 | Sets border of the highlighted area. 155 | 156 | `Default: 3` 157 | 158 | ### html2canvasURL (String) 159 | 160 | The URL where the plugin can download html2canvas.js from. 161 | 162 | `Default: html2canvas.js` 163 | 164 | ### tpl.description / tpl.highlighter / tpl.overview / tpl.submitSuccess / tpl.submitError (String / HTML) 165 | 166 | The template of the plugin. You could change it any time, but keep in mind to keep the elements' ids and classes so the script won't break. 167 | 168 | `Default: ...` 169 | 170 | ### onClose (Function) 171 | 172 | Function that runs when you close the plugin. 173 | 174 | `Default: null` 175 | 176 | ### screenshotStroke (Boolean) 177 | 178 | Changing to `false` will remove the borders from the highlighted areas when taking the screenshot. 179 | 180 | `Default: true` 181 | 182 | ### highlightElement (Boolean) 183 | 184 | By default when you move your cursor over an element the plugin will temporarily highlight it until you move your cursor out of that area. 185 | I'm not exactly sure whether it's a good thing or not, but Google has it, so yeah. 186 | 187 | `Default: true` 188 | 189 | ### initialBox (Boolean) 190 | 191 | By Setting this true the user will have to describe the bug/idea before being able to highlight the area. 192 | 193 | `Default: false` 194 | 195 | ### feedbackButton (String) 196 | 197 | Define a custom button instead of the default button that appears on the lower right corner. 198 | 199 | `Default: .feedback-btn` 200 | 201 | ### showDescriptionModal (Boolean) 202 | 203 | Sets whether the next modal for entering description should appear or not 204 | 205 | `Default: true` 206 | 207 | ### onScreenshotTaken (Function) 208 | 209 | A callback function to be called when clicking on take screenshot button. The callback function's prototype is `function(post)` 210 | 211 | `Default: {}` 212 | 213 | ### isDraggable (Boolean) 214 | 215 | Sets whether the user will be able to drag the feedback options modal or not 216 | 217 | `Default: true` 218 | 219 | ## //TODO List 220 | 221 | * Pulling jQuery out into a more classical AngularJS Directive rather than just wrapping the jQuery plugin. -------------------------------------------------------------------------------- /dist/angular-send-feedback.min.css: -------------------------------------------------------------------------------- 1 | .feedback-btn{position:fixed;right:60px;bottom:-3px;width:auto;font-size:14px}#feedback-module p{font-size:13px}#feedback-note-tmp{width:444px;height:auto;min-height:90px;padding:4px;font-family:Arial,sans-serif;outline:0}#feedback-note-tmp:focus,#feedback-overview-note:focus{border:1px solid #64b7cc}#feedback-canvas{position:absolute;top:0;left:0}#feedback-welcome{position:fixed;top:30%;left:50%;display:block;margin-left:-270px}.feedback-logo{width:34px;height:32px;padding-left:40px;margin-bottom:16px;font-size:16px;font-weight:normal;line-height:32px;background:url(icons.png) 0 0 no-repeat}.feedback-next-btn{float:right;width:72px;height:29px;padding:0 8px;font-size:13px;line-height:27px}.feedback-back-btn{float:right;width:72px;height:29px;padding:0 8px;margin-right:20px;font-size:13px;line-height:27px}.feedback-submit-btn{float:right;width:72px;height:29px;padding:0 8px;font-size:13px;line-height:27px}.feedback-close-btn{float:right;width:72px;height:29px;padding:0 8px;font-size:13px;line-height:27px}.feedback-helper{cursor:default;background:rgba(0,0,0,0)}.feedback-helper[data-type="highlight"]>.feedback-helper-inner{background:rgba(0,68,255,0.1)}#feedback-close{position:absolute;width:30px;height:30px;cursor:pointer;background:url(icons.png) 0 -64px}.feedback-wizard-close{position:absolute;top:2px;right:2px;width:30px;height:30px;cursor:pointer;background:url(icons.png) 0 -34px;opacity:.65}.feedback-wizard-close:hover{opacity:1}#feedback-welcome-error,#feedback-overview-error{display:none;float:right;margin-right:30px;font-size:13px;line-height:29px;color:#f13e3e}#feedback-overview-error{margin-top:20px}#feedback-highlighter{position:fixed;right:100px;bottom:100px;display:none;width:540px;height:275px}#feedback-overview{position:fixed;top:10%;left:50%;display:none;width:840px!important;height:auto;margin-left:-420px}#feedback-submit-error,#feedback-submit-success{position:fixed;top:30%;left:50%;display:block;width:600px;height:auto;margin-left:-300px}.feedback-btn{z-index:40000;padding:10px;outline:0;-webkit-box-shadow:0 4px 16px rgba(0,0,0,0.2);-moz-box-shadow:0 4px 16px rgba(0,0,0,0.2);box-shadow:0 4px 16px rgba(0,0,0,0.2);background-clip:padding-box}.feedback-btn-gray{font-family:'Open sans';color:#444;text-align:center;cursor:pointer;background-color:#f5f5f5;background-image:-webkit-linear-gradient(top,#f5f5f5,#f1f1f1);background-image:-moz-linear-gradient(top,#f5f5f5,#f1f1f1);background-image:-ms-linear-gradient(top,#f5f5f5,#f1f1f1);background-image:-o-linear-gradient(top,#f5f5f5,#f1f1f1);background-image:linear-gradient(top,#f5f5f5,#f1f1f1);border:1px solid #dcdcdc;border:1px solid rgba(0,0,0,0.1);border-radius:2px}.feedback-btn-gray:hover{color:#333;background-color:#f8f8f8;background-image:-webkit-linear-gradient(top,#f8f8f8,#f1f1f1);background-image:-moz-linear-gradient(top,#f8f8f8,#f1f1f1);background-image:-ms-linear-gradient(top,#f8f8f8,#f1f1f1);background-image:-o-linear-gradient(top,#f8f8f8,#f1f1f1);background-image:linear-gradient(top,#f8f8f8,#f1f1f1);border:1px solid #c6c6c6}.feedback-btn-blue{font-family:'Open sans';color:#fff;text-align:center;cursor:pointer;background-color:#357ae8;background-image:-webkit-linear-gradient(top,#4d90fe,#357ae8);background-image:-moz-linear-gradient(top,#4d90fe,#357ae8);background-image:-ms-linear-gradient(top,#4d90fe,#357ae8);background-image:-o-linear-gradient(top,#4d90fe,#357ae8);background-image:linear-gradient(top,#4d90fe,#357ae8);border:1px solid #2f5bb7;border-radius:2px}#feedback-note-tmp,#feedback-overview-note{resize:none}#feedback-welcome,#feedback-highlighter,#feedback-overview,#feedback-submit-success,#feedback-submit-error{z-index:40000;width:540px;padding:30px 42px;font-family:Arial,sans-serif;background:#fff;border:1px solid rgba(0,0,0,0.333);outline:0;-webkit-transform:translateZ();-webkit-box-shadow:0 4px 16px rgba(0,0,0,0.2);-moz-box-shadow:0 4px 16px rgba(0,0,0,0.2);box-shadow:0 4px 16px rgba(0,0,0,0.2);-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box}.feedback-sethighlight,.feedback-setblackout{display:inline-block;float:left;height:30px;min-width:90px;padding:0 8px;margin-right:16px;font-size:11px;font-weight:bold;line-height:28px;color:#444;text-align:center;white-space:nowrap;cursor:default;background-color:#f5f5f5;background-image:-webkit-linear-gradient(top,#f5f5f5,#f1f1f1);background-image:-moz-linear-gradient(top,#f5f5f5,#f1f1f1);background-image:-ms-linear-gradient(top,#f5f5f5,#f1f1f1);background-image:-o-linear-gradient(top,#f5f5f5,#f1f1f1);background-image:linear-gradient(top,#f5f5f5,#f1f1f1);border:1px solid #dcdcdc;border:1px solid rgba(0,0,0,0.1);-webkit-border-radius:2px;-moz-border-radius:2px;border-radius:2px;outline:0;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}.feedback-setblackout{margin-top:10px;clear:both}.feedback-sethighlight div{float:left;width:16px;height:16px;margin-top:7px;background:url(icons.png) 0 -94px}.feedback-setblackout div{float:left;width:16px;height:16px;margin-top:7px;background:url(icons.png) -16px -94px}.feedback-sethighlight:hover,.feedback-setblackout:hover{color:#333;background-color:#f8f8f8;background-image:-webkit-linear-gradient(top,#f8f8f8,#f1f1f1);background-image:-moz-linear-gradient(top,#f8f8f8,#f1f1f1);background-image:-ms-linear-gradient(top,#f8f8f8,#f1f1f1);background-image:-o-linear-gradient(top,#f8f8f8,#f1f1f1);background-image:linear-gradient(top,#f8f8f8,#f1f1f1);border:1px solid #c6c6c6;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}.feedback-active{color:#333;background-color:#eee;background-image:-webkit-linear-gradient(top,#eee,#e0e0e0);background-image:-moz-linear-gradient(top,#eee,#e0e0e0);background-image:-ms-linear-gradient(top,#eee,#e0e0e0);background-image:-o-linear-gradient(top,#eee,#e0e0e0);background-image:linear-gradient(top,#eee,#e0e0e0);border:1px solid #ccc;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,0.1);-moz-box-shadow:inset 0 1px 2px rgba(0,0,0,0.1);box-shadow:inset 0 1px 2px rgba(0,0,0,0.1)}#feedback-highlighter label{float:left;margin:0 0 0 10px;font-size:13px;font-weight:normal;line-height:30px}#feedback-highlighter label.lower{margin-top:10px}.feedback-buttons{float:right;margin-top:20px;clear:both}#feedback-module h3{margin:8px 0;font-size:15px;font-weight:bold}.feedback-additional{margin-bottom:20px!important}#feedback-overview-description{float:left}#feedback-overview-note{width:314px;height:90px;padding:4px;font-family:Arial,sans-serif;outline:0}#feedback-overview-screenshot{float:right}.feedback-screenshot{max-width:396px;padding:1px;border:1px solid #adadad}#feedback-overview-description-text span{padding-left:10px;margin:8px 0;margin-left:26px;font-size:14px;color:#666;background:url(icons.png) -30px -34px no-repeat}#feedback-browser-info,#feedback-page-info,#feedback-timestamp,#feedback-page-structure,#feedback-additional-none{display:none;margin-top:16px} -------------------------------------------------------------------------------- /dist/angular-send-feedback.less: -------------------------------------------------------------------------------- 1 | .feedback-btn { 2 | font-size: 14px; 3 | position: fixed; 4 | bottom: -3px; 5 | right: 60px; 6 | width: auto; 7 | } 8 | #feedback-module p { font-size: 13px } 9 | #feedback-note-tmp { 10 | width: 444px; 11 | height: auto; 12 | min-height: 90px; 13 | outline: none; 14 | font-family: Arial,sans-serif; 15 | padding: 4px; 16 | } 17 | #feedback-note-tmp:focus, 18 | #feedback-overview-note:focus { border: 1px solid #64b7cc } 19 | #feedback-canvas { 20 | position: absolute; 21 | top: 0; 22 | left: 0; 23 | } 24 | #feedback-welcome { 25 | top: 30%; 26 | left: 50%; 27 | margin-left: -270px; 28 | display: block; 29 | position: fixed; 30 | } 31 | .feedback-logo { 32 | background: url(icons.png) -0px -0px no-repeat; 33 | width: 34px; 34 | margin-bottom: 16px; 35 | font-size: 16px; 36 | font-weight: normal; 37 | line-height: 32px; 38 | padding-left: 40px; 39 | height: 32px; 40 | } 41 | .feedback-next-btn { 42 | width: 72px; 43 | height: 29px; 44 | line-height: 27px; 45 | float: right; 46 | font-size: 13px; 47 | padding: 0 8px; 48 | } 49 | .feedback-back-btn { 50 | width: 72px; 51 | height: 29px; 52 | line-height: 27px; 53 | float: right; 54 | font-size: 13px; 55 | padding: 0 8px; 56 | margin-right: 20px; 57 | } 58 | .feedback-submit-btn { 59 | width: 72px; 60 | height: 29px; 61 | line-height: 27px; 62 | float: right; 63 | font-size: 13px; 64 | padding: 0 8px; 65 | } 66 | .feedback-close-btn { 67 | width: 72px; 68 | height: 29px; 69 | line-height: 27px; 70 | float: right; 71 | font-size: 13px; 72 | padding: 0 8px; 73 | } 74 | .feedback-helper { 75 | background: rgba(0,0,0,0); 76 | cursor: default; 77 | } 78 | .feedback-helper[data-type="highlight"]>.feedback-helper-inner { background: rgba(0,68,255,0.1) } 79 | #feedback-close { 80 | cursor: pointer; 81 | position: absolute; 82 | background: url(icons.png) -0px -64px; 83 | width: 30px; 84 | height: 30px; 85 | } 86 | .feedback-wizard-close { 87 | cursor: pointer; 88 | position: absolute; 89 | top: 2px; 90 | right: 2px; 91 | background: url(icons.png) -0px -34px; 92 | width: 30px; 93 | height: 30px; 94 | opacity: 0.65; 95 | } 96 | .feedback-wizard-close:hover { opacity: 1 } 97 | #feedback-welcome-error, 98 | #feedback-overview-error { 99 | display: none; 100 | color: #f13e3e; 101 | float: right; 102 | margin-right: 30px; 103 | font-size: 13px; 104 | line-height: 29px; 105 | } 106 | #feedback-overview-error { margin-top: 20px } 107 | #feedback-highlighter { 108 | display: none; 109 | bottom: 100px; 110 | right: 100px; 111 | position: fixed; 112 | width: 540px; 113 | height: 275px; 114 | } 115 | #feedback-overview { 116 | display: none; 117 | top: 10%; 118 | left: 50%; 119 | margin-left: -420px; 120 | position: fixed; 121 | width: 840px!important; 122 | height: auto; 123 | } 124 | #feedback-submit-error, 125 | #feedback-submit-success { 126 | top: 30%; 127 | left: 50%; 128 | margin-left: -300px; 129 | display: block; 130 | position: fixed; 131 | width: 600px; 132 | height: auto; 133 | } 134 | .feedback-btn { 135 | padding: 10px; 136 | outline: 0; 137 | background-clip: padding-box; 138 | -webkit-box-shadow: 0 4px 16px rgba(0,0,0,.2); 139 | -moz-box-shadow: 0 4px 16px rgba(0,0,0,.2); 140 | box-shadow: 0 4px 16px rgba(0,0,0,.2); 141 | z-index: 40000; 142 | } 143 | .feedback-btn-gray { 144 | text-align: center; 145 | cursor: pointer; 146 | font-family: 'Open sans'; 147 | border: 1px solid #dcdcdc; 148 | border: 1px solid rgba(0,0,0,0.1); 149 | color: #444; 150 | border-radius: 2px; 151 | background-color: #f5f5f5; 152 | background-image: -webkit-linear-gradient(top,#f5f5f5,#f1f1f1); 153 | background-image: -moz-linear-gradient(top,#f5f5f5,#f1f1f1); 154 | background-image: -ms-linear-gradient(top,#f5f5f5,#f1f1f1); 155 | background-image: -o-linear-gradient(top,#f5f5f5,#f1f1f1); 156 | background-image: linear-gradient(top,#f5f5f5,#f1f1f1); 157 | } 158 | .feedback-btn-gray:hover { 159 | color: #333; 160 | border: 1px solid #c6c6c6; 161 | background-color: #f8f8f8; 162 | background-image: -webkit-linear-gradient(top,#f8f8f8,#f1f1f1); 163 | background-image: -moz-linear-gradient(top,#f8f8f8,#f1f1f1); 164 | background-image: -ms-linear-gradient(top,#f8f8f8,#f1f1f1); 165 | background-image: -o-linear-gradient(top,#f8f8f8,#f1f1f1); 166 | background-image: linear-gradient(top,#f8f8f8,#f1f1f1); 167 | } 168 | .feedback-btn-blue { 169 | text-align: center; 170 | cursor: pointer; 171 | font-family: 'Open sans'; 172 | border-radius: 2px; 173 | background-color: #357ae8; 174 | background-image: -webkit-linear-gradient(top,#4d90fe,#357ae8); 175 | background-image: -moz-linear-gradient(top,#4d90fe,#357ae8); 176 | background-image: -ms-linear-gradient(top,#4d90fe,#357ae8); 177 | background-image: -o-linear-gradient(top,#4d90fe,#357ae8); 178 | background-image: linear-gradient(top,#4d90fe,#357ae8); 179 | border: 1px solid #2f5bb7; 180 | color: #fff; 181 | } 182 | #feedback-note-tmp, 183 | #feedback-overview-note { resize: none } 184 | #feedback-welcome, 185 | #feedback-highlighter, 186 | #feedback-overview, 187 | #feedback-submit-success, 188 | #feedback-submit-error { 189 | font-family: Arial,sans-serif; 190 | z-index: 40000; 191 | background: #fff; 192 | border: 1px solid rgba(0,0,0,.333); 193 | padding: 30px 42px; 194 | width: 540px; 195 | border: 1px solid rgba(0,0,0,.333); 196 | outline: 0; 197 | -webkit-box-shadow: 0 4px 16px rgba(0,0,0,.2); 198 | -moz-box-shadow: 0 4px 16px rgba(0,0,0,.2); 199 | box-shadow: 0 4px 16px rgba(0,0,0,.2); 200 | background: #fff; 201 | background-clip: padding-box; 202 | box-sizing: border-box; 203 | -moz-box-sizing: border-box; 204 | -webkit-box-sizing: border-box; 205 | -webkit-transform: translateZ(); 206 | } 207 | .feedback-sethighlight, 208 | .feedback-setblackout { 209 | -webkit-box-shadow: none; 210 | -moz-box-shadow: none; 211 | box-shadow: none; 212 | background-color: #f5f5f5; 213 | background-image: -webkit-linear-gradient(top,#f5f5f5,#f1f1f1); 214 | background-image: -moz-linear-gradient(top,#f5f5f5,#f1f1f1); 215 | background-image: -ms-linear-gradient(top,#f5f5f5,#f1f1f1); 216 | background-image: -o-linear-gradient(top,#f5f5f5,#f1f1f1); 217 | background-image: linear-gradient(top,#f5f5f5,#f1f1f1); 218 | color: #444; 219 | border: 1px solid #dcdcdc; 220 | border: 1px solid rgba(0,0,0,0.1); 221 | -webkit-border-radius: 2px; 222 | -moz-border-radius: 2px; 223 | border-radius: 2px; 224 | cursor: default; 225 | font-size: 11px; 226 | font-weight: bold; 227 | text-align: center; 228 | white-space: nowrap; 229 | margin-right: 16px; 230 | height: 30px; 231 | line-height: 28px; 232 | min-width: 90px; 233 | outline: 0; 234 | padding: 0 8px; 235 | display: inline-block; 236 | float: left; 237 | } 238 | .feedback-setblackout { 239 | margin-top: 10px; 240 | clear: both; 241 | } 242 | .feedback-sethighlight div { 243 | background: url(icons.png) 0px -94px; 244 | width: 16px; 245 | height: 16px; 246 | margin-top: 7px; 247 | float: left; 248 | } 249 | .feedback-setblackout div { 250 | background: url(icons.png) -16px -94px; 251 | width: 16px; 252 | height: 16px; 253 | margin-top: 7px; 254 | float: left; 255 | } 256 | .feedback-sethighlight:hover, 257 | .feedback-setblackout:hover { 258 | -webkit-box-shadow: none; 259 | -moz-box-shadow: none; 260 | box-shadow: none; 261 | background-color: #f8f8f8; 262 | background-image: -webkit-linear-gradient(top,#f8f8f8,#f1f1f1); 263 | background-image: -moz-linear-gradient(top,#f8f8f8,#f1f1f1); 264 | background-image: -ms-linear-gradient(top,#f8f8f8,#f1f1f1); 265 | background-image: -o-linear-gradient(top,#f8f8f8,#f1f1f1); 266 | background-image: linear-gradient(top,#f8f8f8,#f1f1f1); 267 | border: 1px solid #c6c6c6; 268 | color: #333; 269 | } 270 | .feedback-active { 271 | -webkit-box-shadow: inset 0 1px 2px rgba(0,0,0,.1); 272 | -moz-box-shadow: inset 0 1px 2px rgba(0,0,0,.1); 273 | box-shadow: inset 0 1px 2px rgba(0,0,0,.1); 274 | background-color: #eee; 275 | background-image: -webkit-linear-gradient(top,#eee,#e0e0e0); 276 | background-image: -moz-linear-gradient(top,#eee,#e0e0e0); 277 | background-image: -ms-linear-gradient(top,#eee,#e0e0e0); 278 | background-image: -o-linear-gradient(top,#eee,#e0e0e0); 279 | background-image: linear-gradient(top,#eee,#e0e0e0); 280 | border: 1px solid #ccc; 281 | color: #333; 282 | } 283 | #feedback-highlighter label { 284 | float: left; 285 | margin: 0 0 0 10px; 286 | line-height: 30px; 287 | font-size: 13px; 288 | font-weight: normal; 289 | } 290 | #feedback-highlighter label.lower { margin-top: 10px } 291 | .feedback-buttons { 292 | float: right; 293 | margin-top: 20px; 294 | clear: both; 295 | } 296 | #feedback-module h3 { 297 | font-weight: bold; 298 | font-size: 15px; 299 | margin: 8px 0; 300 | } 301 | .feedback-additional { margin-bottom: 20px!important } 302 | #feedback-overview-description { float: left } 303 | #feedback-overview-note { 304 | width: 314px; 305 | padding: 4px; 306 | height: 90px; 307 | outline: none; 308 | font-family: Arial,sans-serif; 309 | } 310 | #feedback-overview-screenshot { float: right } 311 | .feedback-screenshot { 312 | max-width: 396px; 313 | padding: 1px; 314 | border: 1px solid #adadad; 315 | } 316 | #feedback-overview-description-text span { 317 | font-size: 14px; 318 | margin: 8px 0; 319 | color: #666; 320 | padding-left: 10px; 321 | background: url(icons.png) -30px -34px no-repeat; 322 | margin-left: 26px; 323 | } 324 | #feedback-browser-info, 325 | #feedback-page-info, 326 | #feedback-timestamp, 327 | #feedback-page-structure, 328 | #feedback-additional-none { 329 | margin-top: 16px; 330 | display: none; 331 | } 332 | -------------------------------------------------------------------------------- /src/angular-send-feedback.less: -------------------------------------------------------------------------------- 1 | .feedback-btn { 2 | font-size: 14px; 3 | position: fixed; 4 | bottom: -3px; 5 | right: 60px; 6 | width: auto; 7 | } 8 | #feedback-module p { font-size: 13px } 9 | #feedback-note-tmp { 10 | width: 444px; 11 | height: auto; 12 | min-height: 90px; 13 | outline: none; 14 | font-family: Arial,sans-serif; 15 | padding: 4px; 16 | } 17 | #feedback-note-tmp:focus, 18 | #feedback-overview-note:focus { border: 1px solid #64b7cc } 19 | #feedback-canvas { 20 | position: absolute; 21 | top: 0; 22 | left: 0; 23 | } 24 | #feedback-welcome { 25 | top: 30%; 26 | left: 50%; 27 | margin-left: -270px; 28 | display: block; 29 | position: fixed; 30 | } 31 | .feedback-logo { 32 | background: url(icons.png) -0px -0px no-repeat; 33 | width: 34px; 34 | margin-bottom: 16px; 35 | font-size: 16px; 36 | font-weight: normal; 37 | line-height: 32px; 38 | padding-left: 40px; 39 | height: 32px; 40 | } 41 | .feedback-next-btn { 42 | width: 72px; 43 | height: 29px; 44 | line-height: 27px; 45 | float: right; 46 | font-size: 13px; 47 | padding: 0 8px; 48 | } 49 | .feedback-back-btn { 50 | width: 72px; 51 | height: 29px; 52 | line-height: 27px; 53 | float: right; 54 | font-size: 13px; 55 | padding: 0 8px; 56 | margin-right: 20px; 57 | } 58 | .feedback-submit-btn { 59 | width: 72px; 60 | height: 29px; 61 | line-height: 27px; 62 | float: right; 63 | font-size: 13px; 64 | padding: 0 8px; 65 | } 66 | .feedback-close-btn { 67 | width: 72px; 68 | height: 29px; 69 | line-height: 27px; 70 | float: right; 71 | font-size: 13px; 72 | padding: 0 8px; 73 | } 74 | .feedback-helper { 75 | background: rgba(0,0,0,0); 76 | cursor: default; 77 | } 78 | .feedback-helper[data-type="highlight"]>.feedback-helper-inner { background: rgba(0,68,255,0.1) } 79 | #feedback-close { 80 | cursor: pointer; 81 | position: absolute; 82 | background: url(icons.png) -0px -64px; 83 | width: 30px; 84 | height: 30px; 85 | } 86 | .feedback-wizard-close { 87 | cursor: pointer; 88 | position: absolute; 89 | top: 2px; 90 | right: 2px; 91 | background: url(icons.png) -0px -34px; 92 | width: 30px; 93 | height: 30px; 94 | opacity: 0.65; 95 | } 96 | .feedback-wizard-close:hover { opacity: 1 } 97 | #feedback-welcome-error, 98 | #feedback-overview-error { 99 | display: none; 100 | color: #f13e3e; 101 | float: right; 102 | margin-right: 30px; 103 | font-size: 13px; 104 | line-height: 29px; 105 | } 106 | #feedback-overview-error { margin-top: 20px } 107 | #feedback-highlighter { 108 | display: none; 109 | bottom: 100px; 110 | right: 100px; 111 | position: fixed; 112 | width: 540px; 113 | height: 275px; 114 | } 115 | #feedback-overview { 116 | display: none; 117 | top: 10%; 118 | left: 50%; 119 | margin-left: -420px; 120 | position: fixed; 121 | width: 840px!important; 122 | height: auto; 123 | } 124 | #feedback-submit-error, 125 | #feedback-submit-success { 126 | top: 30%; 127 | left: 50%; 128 | margin-left: -300px; 129 | display: block; 130 | position: fixed; 131 | width: 600px; 132 | height: auto; 133 | } 134 | .feedback-btn { 135 | padding: 10px; 136 | outline: 0; 137 | background-clip: padding-box; 138 | -webkit-box-shadow: 0 4px 16px rgba(0,0,0,.2); 139 | -moz-box-shadow: 0 4px 16px rgba(0,0,0,.2); 140 | box-shadow: 0 4px 16px rgba(0,0,0,.2); 141 | z-index: 40000; 142 | } 143 | .feedback-btn-gray { 144 | text-align: center; 145 | cursor: pointer; 146 | font-family: 'Open sans'; 147 | border: 1px solid #dcdcdc; 148 | border: 1px solid rgba(0,0,0,0.1); 149 | color: #444; 150 | border-radius: 2px; 151 | background-color: #f5f5f5; 152 | background-image: -webkit-linear-gradient(top,#f5f5f5,#f1f1f1); 153 | background-image: -moz-linear-gradient(top,#f5f5f5,#f1f1f1); 154 | background-image: -ms-linear-gradient(top,#f5f5f5,#f1f1f1); 155 | background-image: -o-linear-gradient(top,#f5f5f5,#f1f1f1); 156 | background-image: linear-gradient(top,#f5f5f5,#f1f1f1); 157 | } 158 | .feedback-btn-gray:hover { 159 | color: #333; 160 | border: 1px solid #c6c6c6; 161 | background-color: #f8f8f8; 162 | background-image: -webkit-linear-gradient(top,#f8f8f8,#f1f1f1); 163 | background-image: -moz-linear-gradient(top,#f8f8f8,#f1f1f1); 164 | background-image: -ms-linear-gradient(top,#f8f8f8,#f1f1f1); 165 | background-image: -o-linear-gradient(top,#f8f8f8,#f1f1f1); 166 | background-image: linear-gradient(top,#f8f8f8,#f1f1f1); 167 | } 168 | .feedback-btn-blue { 169 | text-align: center; 170 | cursor: pointer; 171 | font-family: 'Open sans'; 172 | border-radius: 2px; 173 | background-color: #357ae8; 174 | background-image: -webkit-linear-gradient(top,#4d90fe,#357ae8); 175 | background-image: -moz-linear-gradient(top,#4d90fe,#357ae8); 176 | background-image: -ms-linear-gradient(top,#4d90fe,#357ae8); 177 | background-image: -o-linear-gradient(top,#4d90fe,#357ae8); 178 | background-image: linear-gradient(top,#4d90fe,#357ae8); 179 | border: 1px solid #2f5bb7; 180 | color: #fff; 181 | } 182 | #feedback-note-tmp, 183 | #feedback-overview-note { resize: none } 184 | #feedback-welcome, 185 | #feedback-highlighter, 186 | #feedback-overview, 187 | #feedback-submit-success, 188 | #feedback-submit-error { 189 | font-family: Arial,sans-serif; 190 | z-index: 40000; 191 | background: #fff; 192 | border: 1px solid rgba(0,0,0,.333); 193 | padding: 30px 42px; 194 | width: 540px; 195 | border: 1px solid rgba(0,0,0,.333); 196 | outline: 0; 197 | -webkit-box-shadow: 0 4px 16px rgba(0,0,0,.2); 198 | -moz-box-shadow: 0 4px 16px rgba(0,0,0,.2); 199 | box-shadow: 0 4px 16px rgba(0,0,0,.2); 200 | background: #fff; 201 | background-clip: padding-box; 202 | box-sizing: border-box; 203 | -moz-box-sizing: border-box; 204 | -webkit-box-sizing: border-box; 205 | -webkit-transform: translateZ(); 206 | } 207 | .feedback-sethighlight, 208 | .feedback-setblackout { 209 | -webkit-box-shadow: none; 210 | -moz-box-shadow: none; 211 | box-shadow: none; 212 | background-color: #f5f5f5; 213 | background-image: -webkit-linear-gradient(top,#f5f5f5,#f1f1f1); 214 | background-image: -moz-linear-gradient(top,#f5f5f5,#f1f1f1); 215 | background-image: -ms-linear-gradient(top,#f5f5f5,#f1f1f1); 216 | background-image: -o-linear-gradient(top,#f5f5f5,#f1f1f1); 217 | background-image: linear-gradient(top,#f5f5f5,#f1f1f1); 218 | color: #444; 219 | border: 1px solid #dcdcdc; 220 | border: 1px solid rgba(0,0,0,0.1); 221 | -webkit-border-radius: 2px; 222 | -moz-border-radius: 2px; 223 | border-radius: 2px; 224 | cursor: default; 225 | font-size: 11px; 226 | font-weight: bold; 227 | text-align: center; 228 | white-space: nowrap; 229 | margin-right: 16px; 230 | height: 30px; 231 | line-height: 28px; 232 | min-width: 90px; 233 | outline: 0; 234 | padding: 0 8px; 235 | display: inline-block; 236 | float: left; 237 | } 238 | .feedback-setblackout { 239 | margin-top: 10px; 240 | clear: both; 241 | } 242 | .feedback-sethighlight div { 243 | background: url(icons.png) 0px -94px; 244 | width: 16px; 245 | height: 16px; 246 | margin-top: 7px; 247 | float: left; 248 | } 249 | .feedback-setblackout div { 250 | background: url(icons.png) -16px -94px; 251 | width: 16px; 252 | height: 16px; 253 | margin-top: 7px; 254 | float: left; 255 | } 256 | .feedback-sethighlight:hover, 257 | .feedback-setblackout:hover { 258 | -webkit-box-shadow: none; 259 | -moz-box-shadow: none; 260 | box-shadow: none; 261 | background-color: #f8f8f8; 262 | background-image: -webkit-linear-gradient(top,#f8f8f8,#f1f1f1); 263 | background-image: -moz-linear-gradient(top,#f8f8f8,#f1f1f1); 264 | background-image: -ms-linear-gradient(top,#f8f8f8,#f1f1f1); 265 | background-image: -o-linear-gradient(top,#f8f8f8,#f1f1f1); 266 | background-image: linear-gradient(top,#f8f8f8,#f1f1f1); 267 | border: 1px solid #c6c6c6; 268 | color: #333; 269 | } 270 | .feedback-active { 271 | -webkit-box-shadow: inset 0 1px 2px rgba(0,0,0,.1); 272 | -moz-box-shadow: inset 0 1px 2px rgba(0,0,0,.1); 273 | box-shadow: inset 0 1px 2px rgba(0,0,0,.1); 274 | background-color: #eee; 275 | background-image: -webkit-linear-gradient(top,#eee,#e0e0e0); 276 | background-image: -moz-linear-gradient(top,#eee,#e0e0e0); 277 | background-image: -ms-linear-gradient(top,#eee,#e0e0e0); 278 | background-image: -o-linear-gradient(top,#eee,#e0e0e0); 279 | background-image: linear-gradient(top,#eee,#e0e0e0); 280 | border: 1px solid #ccc; 281 | color: #333; 282 | } 283 | #feedback-highlighter label { 284 | float: left; 285 | margin: 0 0 0 10px; 286 | line-height: 30px; 287 | font-size: 13px; 288 | font-weight: normal; 289 | } 290 | #feedback-highlighter label.lower { margin-top: 10px } 291 | .feedback-buttons { 292 | float: right; 293 | margin-top: 20px; 294 | clear: both; 295 | } 296 | #feedback-module h3 { 297 | font-weight: bold; 298 | font-size: 15px; 299 | margin: 8px 0; 300 | } 301 | .feedback-additional { margin-bottom: 20px!important } 302 | #feedback-overview-description { float: left } 303 | #feedback-overview-note { 304 | width: 314px; 305 | padding: 4px; 306 | height: 90px; 307 | outline: none; 308 | font-family: Arial,sans-serif; 309 | } 310 | #feedback-overview-screenshot { float: right } 311 | .feedback-screenshot { 312 | max-width: 396px; 313 | padding: 1px; 314 | border: 1px solid #adadad; 315 | } 316 | #feedback-overview-description-text span { 317 | font-size: 14px; 318 | margin: 8px 0; 319 | color: #666; 320 | padding-left: 10px; 321 | background: url(icons.png) -30px -34px no-repeat; 322 | margin-left: 26px; 323 | } 324 | #feedback-browser-info, 325 | #feedback-page-info, 326 | #feedback-timestamp, 327 | #feedback-page-structure, 328 | #feedback-additional-none { 329 | margin-top: 16px; 330 | display: none; 331 | } 332 | -------------------------------------------------------------------------------- /dist/angular-send-feedback.css: -------------------------------------------------------------------------------- 1 | .feedback-btn { 2 | position: fixed; 3 | right: 60px; 4 | bottom: -3px; 5 | width: auto; 6 | font-size: 14px; 7 | } 8 | 9 | #feedback-module p { 10 | font-size: 13px; 11 | } 12 | 13 | #feedback-note-tmp { 14 | width: 444px; 15 | height: auto; 16 | min-height: 90px; 17 | padding: 4px; 18 | font-family: Arial, sans-serif; 19 | outline: none; 20 | } 21 | 22 | #feedback-note-tmp:focus, 23 | #feedback-overview-note:focus { 24 | border: 1px solid #64b7cc; 25 | } 26 | 27 | #feedback-canvas { 28 | position: absolute; 29 | top: 0; 30 | left: 0; 31 | } 32 | 33 | #feedback-welcome { 34 | position: fixed; 35 | top: 30%; 36 | left: 50%; 37 | display: block; 38 | margin-left: -270px; 39 | } 40 | 41 | .feedback-logo { 42 | width: 34px; 43 | height: 32px; 44 | padding-left: 40px; 45 | margin-bottom: 16px; 46 | font-size: 16px; 47 | font-weight: normal; 48 | line-height: 32px; 49 | background: url(icons.png) 0px 0px no-repeat; 50 | } 51 | 52 | .feedback-next-btn { 53 | float: right; 54 | width: 72px; 55 | height: 29px; 56 | padding: 0 8px; 57 | font-size: 13px; 58 | line-height: 27px; 59 | } 60 | 61 | .feedback-back-btn { 62 | float: right; 63 | width: 72px; 64 | height: 29px; 65 | padding: 0 8px; 66 | margin-right: 20px; 67 | font-size: 13px; 68 | line-height: 27px; 69 | } 70 | 71 | .feedback-submit-btn { 72 | float: right; 73 | width: 72px; 74 | height: 29px; 75 | padding: 0 8px; 76 | font-size: 13px; 77 | line-height: 27px; 78 | } 79 | 80 | .feedback-close-btn { 81 | float: right; 82 | width: 72px; 83 | height: 29px; 84 | padding: 0 8px; 85 | font-size: 13px; 86 | line-height: 27px; 87 | } 88 | 89 | .feedback-helper { 90 | cursor: default; 91 | background: rgba(0, 0, 0, 0); 92 | } 93 | 94 | .feedback-helper[data-type="highlight"] > .feedback-helper-inner { 95 | background: rgba(0, 68, 255, 0.1); 96 | } 97 | 98 | #feedback-close { 99 | position: absolute; 100 | width: 30px; 101 | height: 30px; 102 | cursor: pointer; 103 | background: url(icons.png) 0px -64px; 104 | } 105 | 106 | .feedback-wizard-close { 107 | position: absolute; 108 | top: 2px; 109 | right: 2px; 110 | width: 30px; 111 | height: 30px; 112 | cursor: pointer; 113 | background: url(icons.png) 0px -34px; 114 | opacity: 0.65; 115 | } 116 | 117 | .feedback-wizard-close:hover { 118 | opacity: 1; 119 | } 120 | 121 | #feedback-welcome-error, 122 | #feedback-overview-error { 123 | display: none; 124 | float: right; 125 | margin-right: 30px; 126 | font-size: 13px; 127 | line-height: 29px; 128 | color: #f13e3e; 129 | } 130 | 131 | #feedback-overview-error { 132 | margin-top: 20px; 133 | } 134 | 135 | #feedback-highlighter { 136 | position: fixed; 137 | right: 100px; 138 | bottom: 100px; 139 | display: none; 140 | width: 540px; 141 | height: 275px; 142 | } 143 | 144 | #feedback-overview { 145 | position: fixed; 146 | top: 10%; 147 | left: 50%; 148 | display: none; 149 | width: 840px!important; 150 | height: auto; 151 | margin-left: -420px; 152 | } 153 | 154 | #feedback-submit-error, 155 | #feedback-submit-success { 156 | position: fixed; 157 | top: 30%; 158 | left: 50%; 159 | display: block; 160 | width: 600px; 161 | height: auto; 162 | margin-left: -300px; 163 | } 164 | 165 | .feedback-btn { 166 | z-index: 40000; 167 | padding: 10px; 168 | outline: 0; 169 | -webkit-box-shadow: 0 4px 16px rgba(0, 0, 0, 0.2); 170 | -moz-box-shadow: 0 4px 16px rgba(0, 0, 0, 0.2); 171 | box-shadow: 0 4px 16px rgba(0, 0, 0, 0.2); 172 | background-clip: padding-box; 173 | } 174 | 175 | .feedback-btn-gray { 176 | font-family: 'Open sans'; 177 | color: #444; 178 | text-align: center; 179 | cursor: pointer; 180 | background-color: #f5f5f5; 181 | background-image: -webkit-linear-gradient(top, #f5f5f5, #f1f1f1); 182 | background-image: -moz-linear-gradient(top, #f5f5f5, #f1f1f1); 183 | background-image: -ms-linear-gradient(top, #f5f5f5, #f1f1f1); 184 | background-image: -o-linear-gradient(top, #f5f5f5, #f1f1f1); 185 | background-image: linear-gradient(top, #f5f5f5, #f1f1f1); 186 | border: 1px solid #dcdcdc; 187 | border: 1px solid rgba(0, 0, 0, 0.1); 188 | border-radius: 2px; 189 | } 190 | 191 | .feedback-btn-gray:hover { 192 | color: #333; 193 | background-color: #f8f8f8; 194 | background-image: -webkit-linear-gradient(top, #f8f8f8, #f1f1f1); 195 | background-image: -moz-linear-gradient(top, #f8f8f8, #f1f1f1); 196 | background-image: -ms-linear-gradient(top, #f8f8f8, #f1f1f1); 197 | background-image: -o-linear-gradient(top, #f8f8f8, #f1f1f1); 198 | background-image: linear-gradient(top, #f8f8f8, #f1f1f1); 199 | border: 1px solid #c6c6c6; 200 | } 201 | 202 | .feedback-btn-blue { 203 | font-family: 'Open sans'; 204 | color: #fff; 205 | text-align: center; 206 | cursor: pointer; 207 | background-color: #357ae8; 208 | background-image: -webkit-linear-gradient(top, #4d90fe, #357ae8); 209 | background-image: -moz-linear-gradient(top, #4d90fe, #357ae8); 210 | background-image: -ms-linear-gradient(top, #4d90fe, #357ae8); 211 | background-image: -o-linear-gradient(top, #4d90fe, #357ae8); 212 | background-image: linear-gradient(top, #4d90fe, #357ae8); 213 | border: 1px solid #2f5bb7; 214 | border-radius: 2px; 215 | } 216 | 217 | #feedback-note-tmp, 218 | #feedback-overview-note { 219 | resize: none; 220 | } 221 | 222 | #feedback-welcome, 223 | #feedback-highlighter, 224 | #feedback-overview, 225 | #feedback-submit-success, 226 | #feedback-submit-error { 227 | z-index: 40000; 228 | width: 540px; 229 | padding: 30px 42px; 230 | font-family: Arial, sans-serif; 231 | background: #fff; 232 | border: 1px solid rgba(0, 0, 0, 0.333); 233 | outline: 0; 234 | -webkit-transform: translateZ(); 235 | -webkit-box-shadow: 0 4px 16px rgba(0, 0, 0, 0.2); 236 | -moz-box-shadow: 0 4px 16px rgba(0, 0, 0, 0.2); 237 | box-shadow: 0 4px 16px rgba(0, 0, 0, 0.2); 238 | -webkit-box-sizing: border-box; 239 | -moz-box-sizing: border-box; 240 | box-sizing: border-box; 241 | background-clip: padding-box; 242 | } 243 | 244 | .feedback-sethighlight, 245 | .feedback-setblackout { 246 | display: inline-block; 247 | float: left; 248 | height: 30px; 249 | min-width: 90px; 250 | padding: 0 8px; 251 | margin-right: 16px; 252 | font-size: 11px; 253 | font-weight: bold; 254 | line-height: 28px; 255 | color: #444; 256 | text-align: center; 257 | white-space: nowrap; 258 | cursor: default; 259 | background-color: #f5f5f5; 260 | background-image: -webkit-linear-gradient(top, #f5f5f5, #f1f1f1); 261 | background-image: -moz-linear-gradient(top, #f5f5f5, #f1f1f1); 262 | background-image: -ms-linear-gradient(top, #f5f5f5, #f1f1f1); 263 | background-image: -o-linear-gradient(top, #f5f5f5, #f1f1f1); 264 | background-image: linear-gradient(top, #f5f5f5, #f1f1f1); 265 | border: 1px solid #dcdcdc; 266 | border: 1px solid rgba(0, 0, 0, 0.1); 267 | -webkit-border-radius: 2px; 268 | -moz-border-radius: 2px; 269 | border-radius: 2px; 270 | outline: 0; 271 | -webkit-box-shadow: none; 272 | -moz-box-shadow: none; 273 | box-shadow: none; 274 | } 275 | 276 | .feedback-setblackout { 277 | margin-top: 10px; 278 | clear: both; 279 | } 280 | 281 | .feedback-sethighlight div { 282 | float: left; 283 | width: 16px; 284 | height: 16px; 285 | margin-top: 7px; 286 | background: url(icons.png) 0px -94px; 287 | } 288 | 289 | .feedback-setblackout div { 290 | float: left; 291 | width: 16px; 292 | height: 16px; 293 | margin-top: 7px; 294 | background: url(icons.png) -16px -94px; 295 | } 296 | 297 | .feedback-sethighlight:hover, 298 | .feedback-setblackout:hover { 299 | color: #333; 300 | background-color: #f8f8f8; 301 | background-image: -webkit-linear-gradient(top, #f8f8f8, #f1f1f1); 302 | background-image: -moz-linear-gradient(top, #f8f8f8, #f1f1f1); 303 | background-image: -ms-linear-gradient(top, #f8f8f8, #f1f1f1); 304 | background-image: -o-linear-gradient(top, #f8f8f8, #f1f1f1); 305 | background-image: linear-gradient(top, #f8f8f8, #f1f1f1); 306 | border: 1px solid #c6c6c6; 307 | -webkit-box-shadow: none; 308 | -moz-box-shadow: none; 309 | box-shadow: none; 310 | } 311 | 312 | .feedback-active { 313 | color: #333; 314 | background-color: #eee; 315 | background-image: -webkit-linear-gradient(top, #eeeeee, #e0e0e0); 316 | background-image: -moz-linear-gradient(top, #eeeeee, #e0e0e0); 317 | background-image: -ms-linear-gradient(top, #eeeeee, #e0e0e0); 318 | background-image: -o-linear-gradient(top, #eeeeee, #e0e0e0); 319 | background-image: linear-gradient(top, #eeeeee, #e0e0e0); 320 | border: 1px solid #ccc; 321 | -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1); 322 | -moz-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1); 323 | box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1); 324 | } 325 | 326 | #feedback-highlighter label { 327 | float: left; 328 | margin: 0 0 0 10px; 329 | font-size: 13px; 330 | font-weight: normal; 331 | line-height: 30px; 332 | } 333 | 334 | #feedback-highlighter label.lower { 335 | margin-top: 10px; 336 | } 337 | 338 | .feedback-buttons { 339 | float: right; 340 | margin-top: 20px; 341 | clear: both; 342 | } 343 | 344 | #feedback-module h3 { 345 | margin: 8px 0; 346 | font-size: 15px; 347 | font-weight: bold; 348 | } 349 | 350 | .feedback-additional { 351 | margin-bottom: 20px !important; 352 | } 353 | 354 | #feedback-overview-description { 355 | float: left; 356 | } 357 | 358 | #feedback-overview-note { 359 | width: 314px; 360 | height: 90px; 361 | padding: 4px; 362 | font-family: Arial, sans-serif; 363 | outline: none; 364 | } 365 | 366 | #feedback-overview-screenshot { 367 | float: right; 368 | } 369 | 370 | .feedback-screenshot { 371 | max-width: 396px; 372 | padding: 1px; 373 | border: 1px solid #adadad; 374 | } 375 | 376 | #feedback-overview-description-text span { 377 | padding-left: 10px; 378 | margin: 8px 0; 379 | margin-left: 26px; 380 | font-size: 14px; 381 | color: #666; 382 | background: url(icons.png) -30px -34px no-repeat; 383 | } 384 | 385 | #feedback-browser-info, 386 | #feedback-page-info, 387 | #feedback-timestamp, 388 | #feedback-page-structure, 389 | #feedback-additional-none { 390 | display: none; 391 | margin-top: 16px; 392 | } -------------------------------------------------------------------------------- /dist/angular-send-feedback.min.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Angular feedback directive similar to Google Feedback 3 | * @version v1.2.0 - 2016-06-28 * @link https://github.com/jacobscarter/angular-feedback 4 | * @author Jacob Carter 5 | * @license MIT License, http://www.opensource.org/licenses/MIT 6 | */ 7 | angular.module("templates-angularsendfeedback",["angularsendfeedback.html"]),angular.module("angularsendfeedback.html",[]).run(["$templateCache",function(a){a.put("angularsendfeedback.html","")}]),angular.module("angular-send-feedback",["templates-angularsendfeedback"]),angular.module("angular-send-feedback").directive("angularFeedback",[function(){return{restrict:"EA",replace:!0,transclude:!0,scope:{options:"="},link:function(a,b,c){!function(a){a.feedback=function(b){function c(){canDraw=!1,a(document).off("mouseenter mouseleave",".feedback-helper"),a(document).off("mouseup keyup"),a(document).off("mousedown",".feedback-setblackout"),a(document).off("mousedown",".feedback-sethighlight"),a(document).off("mousedown click","#feedback-close"),a(document).off("mousedown","#feedback-canvas"),a(document).off("click","#feedback-highlighter-next"),a(document).off("click","#feedback-highlighter-back"),a(document).off("click","#feedback-welcome-next"),a(document).off("click","#feedback-overview-back"),a(document).off("mouseleave","body"),a(document).off("mouseenter",".feedback-helper"),a(document).off("selectstart dragstart",document),a("#feedback-module").off("click",".feedback-wizard-close,.feedback-close-btn"),a(document).off("click","#feedback-submit"),f.highlightElement&&(a(document).off("click","#feedback-canvas"),a(document).off("mousemove","#feedback-canvas")),a('[data-highlighted="true"]').removeAttr("data-highlight-id").removeAttr("data-highlighted"),a("#feedback-module").remove(),a(".feedback-btn").show(),f.onClose.call(this)}function d(b,c){c="undefined"!=typeof c?c:!0,b.clearRect(0,0,a("#feedback-canvas").width(),a("#feedback-canvas").height()),b.fillStyle="rgba(102,102,102,0.5)",b.fillRect(0,0,a("#feedback-canvas").width(),a("#feedback-canvas").height()),a(".feedback-helper").each(function(){"highlight"==a(this).attr("data-type")&&c&&e(b,parseInt(a(this).css("left"),10),parseInt(a(this).css("top"),10),a(this).width(),a(this).height())}),a(".feedback-helper").each(function(){"highlight"==a(this).attr("data-type")&&b.clearRect(parseInt(a(this).css("left"),10),parseInt(a(this).css("top"),10),a(this).width(),a(this).height())}),a(".feedback-helper").each(function(){"blackout"==a(this).attr("data-type")&&(b.fillStyle="rgba(0,0,0,1)",b.fillRect(parseInt(a(this).css("left"),10),parseInt(a(this).css("top"),10),a(this).width(),a(this).height()))})}function e(a,b,c,d,e){a.strokeStyle=f.strokeStyle,a.shadowColor=f.shadowColor,a.shadowOffsetX=f.shadowOffsetX,a.shadowOffsetY=f.shadowOffsetY,a.shadowBlur=f.shadowBlur,a.lineJoin=f.lineJoin,a.lineWidth=f.lineWidth,a.strokeRect(b,c,d,e),a.shadowOffsetX=0,a.shadowOffsetY=0,a.shadowBlur=0,a.lineWidth=1}var f=a.extend({ajaxURL:"",postBrowserInfo:!0,postHTML:!0,postURL:!0,postTimeStamp:!0,proxy:void 0,letterRendering:!1,initButtonText:"Send feedback",strokeStyle:"black",shadowColor:"black",shadowOffsetX:1,shadowOffsetY:1,shadowBlur:10,lineJoin:"bevel",lineWidth:3,html2canvasURL:"html2canvas.js",feedbackButton:".feedback-btn",showDescriptionModal:!0,isDraggable:!0,onScreenshotTaken:function(){},tpl:{initButton:'
',description:'

Feedback lets you send us suggestions about our products. We welcome problem reports, feature ideas and general comments.

Start by writing a brief description:

Next we\'ll let you identify areas of the page related to your description.

Please enter a description.
',highlighter:'

Click and drag on the page to help us better understand your feedback. You can move this dialog if it\'s in the way.

',overview:'

Description

None
Browser Info
Page Info
Time Stamp
Page Structure

Screenshot

Please enter a description.
',submitSuccess:'

Thank you for your feedback. We value every piece of feedback we receive.

We cannot respond individually to every one, but we will use your comments as we strive to improve your experience.

',submitError:'

Sadly an error occurred while sending your feedback. Please try again.

'},onClose:function(){},screenshotStroke:!0,highlightElement:!0,initialBox:!1},b),g=!!window.HTMLCanvasElement,h=".feedback-btn"==f.feedbackButton,i=!1;g&&(h&&a("body").append(f.tpl.initButton),a(document).on("click",f.feedbackButton,function(){h&&a(this).hide(),i||a.getScript(f.html2canvasURL,function(){i=!0});var b=!1,g="",j=a(document).height(),k=a(document).width(),l='
';f.initialBox&&(l+=f.tpl.description),l+=f.tpl.highlighter+f.tpl.overview+'
',a("body").append(l),moduleStyle={position:"absolute",left:"0px",top:"0px"},canvasAttr={width:k,height:j},a("#feedback-module").css(moduleStyle),a("#feedback-canvas").attr(canvasAttr).css("z-index","30000"),f.initialBox||(a("#feedback-highlighter-back").remove(),b=!0,a("#feedback-canvas").css("cursor","crosshair"),a("#feedback-helpers").show(),a("#feedback-welcome").hide(),a("#feedback-highlighter").show()),f.isDraggable&&a("#feedback-highlighter").on("mousedown",function(b){var c=a(this).addClass("feedback-draggable"),d=c.outerHeight(),e=c.outerWidth(),f=c.offset().top+d-b.pageY,g=c.offset().left+e-b.pageX;c.css("z-index",4e4).parents().on("mousemove",function(b){_top=b.pageY+f-d,_left=b.pageX+g-e,_bottom=d-b.pageY,_right=e-b.pageX,_left<0&&(_left=0),_top<0&&(_top=0),_right>a(window).width()&&(_left=a(window).width()-e),_left>a(window).width()-e&&(_left=a(window).width()-e),_bottom>a(document).height()&&(_top=a(document).height()-d),_top>a(document).height()-d&&(_top=a(document).height()-d),a(".feedback-draggable").offset({top:_top,left:_left}).on("mouseup",function(){a(this).removeClass("feedback-draggable")})}),b.preventDefault()}).on("mouseup",function(){a(this).removeClass("feedback-draggable"),a(this).parents().off("mousemove mousedown")});var m=a("#feedback-canvas")[0].getContext("2d");if(m.fillStyle="rgba(102,102,102,0.5)",m.fillRect(0,0,a("#feedback-canvas").width(),a("#feedback-canvas").height()),rect={},drag=!1,highlight=1,post={},f.postBrowserInfo&&(post.browser={},post.browser.appCodeName=navigator.appCodeName,post.browser.appName=navigator.appName,post.browser.appVersion=navigator.appVersion,post.browser.cookieEnabled=navigator.cookieEnabled,post.browser.onLine=navigator.onLine,post.browser.platform=navigator.platform,post.browser.userAgent=navigator.userAgent,post.browser.plugins=[],a.each(navigator.plugins,function(a){post.browser.plugins.push(navigator.plugins[a].name)}),a("#feedback-browser-info").show()),f.postURL&&(post.url=document.URL,a("#feedback-page-info").show()),f.postTimeStamp&&(post.timestamp=(new Date).getTime(),a("#feedback-timestamp").show()),f.postHTML&&(post.html=a("html").html(),a("#feedback-page-structure").show()),f.postBrowserInfo||f.postURL||f.postHTML||a("#feedback-additional-none").show(),a(document).on("mousedown","#feedback-canvas",function(c){b&&(rect.startX=c.pageX-a(this).offset().left,rect.startY=c.pageY-a(this).offset().top,rect.w=0,rect.h=0,drag=!0)}),a(document).on("mouseup",function(){if(b){drag=!1;var c=rect.startY,e=rect.startX,f=rect.w,g=rect.h;if(dtype="highlight",0==f||0==g)return;0>f&&(e+=f,f*=-1),0>g&&(c+=g,g*=-1),c+g>a(document).height()&&(g=a(document).height()-c),e+f>a(document).width()&&(f=a(document).width()-e),0==highlight&&(dtype="blackout"),a("#feedback-helpers").append(''),d(m),rect.w=0}}),a(document).on("mousemove",function(c){b&&drag&&(a("#feedback-highlighter").css("cursor","default"),rect.w=c.pageX-a("#feedback-canvas").offset().left-rect.startX,rect.h=c.pageY-a("#feedback-canvas").offset().top-rect.startY,m.clearRect(0,0,a("#feedback-canvas").width(),a("#feedback-canvas").height()),m.fillStyle="rgba(102,102,102,0.5)",m.fillRect(0,0,a("#feedback-canvas").width(),a("#feedback-canvas").height()),a(".feedback-helper").each(function(){"highlight"==a(this).attr("data-type")&&e(m,parseInt(a(this).css("left"),10),parseInt(a(this).css("top"),10),a(this).width(),a(this).height())}),1==highlight&&(e(m,rect.startX,rect.startY,rect.w,rect.h),m.clearRect(rect.startX,rect.startY,rect.w,rect.h)),a(".feedback-helper").each(function(){"highlight"==a(this).attr("data-type")&&m.clearRect(parseInt(a(this).css("left"),10),parseInt(a(this).css("top"),10),a(this).width(),a(this).height())}),a(".feedback-helper").each(function(){"blackout"==a(this).attr("data-type")&&(m.fillStyle="rgba(0,0,0,1)",m.fillRect(parseInt(a(this).css("left"),10),parseInt(a(this).css("top"),10),a(this).width(),a(this).height()))}),0==highlight&&(m.fillStyle="rgba(0,0,0,0.5)",m.fillRect(rect.startX,rect.startY,rect.w,rect.h)))}),f.highlightElement){var n=[],o=[],p=0;a(document).on("mousemove click","#feedback-canvas",function(c){if(b){d(m),o=[],a("#feedback-canvas").css("cursor","crosshair"),a("* :not(body,script,iframe,div,section,.feedback-btn,#feedback-module *)").each(function(){"true"!==a(this).attr("data-highlighted")&&c.pageX>a(this).offset().left&&c.pageXa(this).offset().top+parseInt(a(this).css("padding-top"),10)&&c.pageY