Commit 7bc7643c authored by Irina's avatar Irina

Merge pull request #1 from iriiiina/v1.3

v1.3
parents f5a9be2b 949b38b9
jiraIssueOpener
===============
<h1>Short Description</h1>
Extension opens JIRA issue in new tab. User needs only to insert issue key.
Chrome extension that opens JIRA issue in new tab
It is useful for developers, analysts or testers who often need to open JIRA issue using its key.
<a href = "http://ivanova-irina.blogspot.com/p/jira-issue-opener.html">Page of JIRA Issue Opener</a>
<h1>Download and Install</h1>
<ul>
<li><strong><a href="https://chrome.google.com/webstore/detail/jira-issue-opener/koceedenfpfaogpnpplkeikokjdnlamj">Install</a></strong> last version from Google Store
</li>
or
<li><strong><a href="https://github.com/iriiiina/JIRA-Issue-Opener">Download</a></strong> source code from GitHub and load extension manually</li>
</ul>
<h1>Questions and Comments</h1>
Any questions or comments are welcome! You can write me an e-mail on <a href="mailto:iriiiina@gmail.com">iriiiina@gmail.com</a> or leave a comment on this page.
<h1>Source Code and Issues</h1>
Source code and issue reporting is available at GitHub: <a href="https://github.com/iriiiina/JIRA-Issue-Opener">https://github.com/iriiiina/JIRA-Issue-Opener</a>
<h1>Screenshots</h1>
<img border="0" src="http://3.bp.blogspot.com/-lXr4C8njBBs/VBmYrnVGTDI/AAAAAAAALXk/k4UpCRoBFBY/s1600/extension.jpg" />&nbsp;
<img border="0" src="http://4.bp.blogspot.com/-Wb3ckR69dJE/VBLcx2KA7uI/AAAAAAAALVw/sgnMzDi3FWA/s1600/options.jpg" height = "190px"/>
<h1>Description</h1>
Basically extension simply adds your issue key to specified URL and opens it in new tab:
<code>URL/browse/KEY</code>
Where <code>URL</code> is parameter, that user should specify in Options page (only one time after installation) and <code>KEY</code> is issue key that user inserts into extension field.
<b>Features</b>
<ul>
<li><code>KEY</code> is case insensitive</li>
<li>All spaces in the beginning and in the end will be trimmed</li>
<li>Skype formatting will be trimmed: <code>[16.09.2014 13:34:34] Irina Ivanova: KEY-776</code> will be recognized as <code>KEY-776</code></li></ul>
<h1>Chrome Tip</h1>
You can configure hot keys for extension in the Google Chrome:
<ul>
<li>open the extensions tab - <a href="chrome://extensions/">chrome://extensions</a></li>
<li>link "Configure commands" at the bottom</li>
<li>choose an extension and type a shortcut</li>
</ul>
Now You can use it completely without a mouse!
<h1>Posts About JIRA Issue Opener</h1>
<table><tbody>
<tr><td><em>September 17, 2014</em></td><td><a href="http://ivanova-irina.blogspot.com/2014/09/jira-issue-opener-v11.html">JIRA Issue Opener v1.1</a></td></tr>
<tr><td><em>September 12, 2014</em></td><td><a href="http://ivanova-irina.blogspot.com/2014/09/jira-issue-opener-v10.html">JIRA Issue Opener v1.0</a></td></tr>
</tbody></table>
body {
background-color: white;
font-family: Arial, sans-serif;
font-size: 14px;
color: black;
padding-left: 50px
}
img {
float: left;
margin: 10px
}
h1 {
color: #205081;
padding-left: 100px
}
p {
color: gray;
padding-left: 50px
}
table {
border-left: 10px;
border-left-color: #205081;
border-left-style: solid
}
td {
vertical-align: top
}
#button {
position: relative;
float: left;
padding-top: 20px;
width: 200px
}
#status {
position: relative;
color: #006600;
width: 200px;
padding-top: 25px;
float: left
}
#error {
position: relative;
color: #CC0000;
padding-top: 25px;
float: left
}
#save {
background-color: #205081;
color: white;
border: 0px;
font-size: 20px;
width: 160px
}
#save:hover {
background-color: #183656
}
a {
color: #205081
}
#contacts {
font-size: 10px
}
\ No newline at end of file
body {
min-width: 230px;
overflow-x: hidden;
background-color: #205081;
font-family: Arial, sans-serif;
font-size: 14px;
color: white
}
input {
font-size: 14px;
color: #000000
}
#error {
font-size: 14px;
color: #CC0000;
padding-bottom: 10px;
text-align: center
}
#info {
float: right;
color: white;
font-size: 10px
}
.description {
text-align: right;
font-size: 11px;
color: #CCCCCC
}
\ No newline at end of file
<!DOCTYPE html>
<!-- Extension opens JIRA issue in new tab
Author: Irina Ivanova, iriiiina@gmail.com
11.09.2014
Tartu, Estonia -->
<html>
<head>
<title>JIRA Issue Opener</title>
<script src='js/openIssue.js' type='text/javascript' charset='utf-8'></script>
<link rel='stylesheet' type='text/css' href='css/style.css' />
</head>
<body>
<div id='error'>
<br/>
</div>
<div id='keyInput'>
<label for='key'>Key:&nbsp;</label>
<input type='text' name='key' id='key' maxlength='100' size='22' autofocus />
<p class='description'>Insert issue key</p>
<p class='description'>Spaces and Skype formatting will be trimmed</p>
<p class='description'>JIRA issue will be opened in new tab</p>
</div>
<div id='info'>
<p>iriiiina@gmail.com v1.2</p>
</div>
</body>
</html>
\ No newline at end of file
function setErrorText(errorText) {
'use strict';
var divError = document.getElementById('error');
divError.innerText = errorText + '\n';
}
function colorBorderToRed(element) {
'use strict';
var border = document.getElementById(element);
border.style.borderColor = '#FF6666';
border.focus();
border.select();
}
function returnError(errorText, element) {
'use strict';
setErrorText(errorText);
colorBorderToRed(element);
throw '';
}
var key,
url;
function setUrl(urlOption) {
'use strict';
if (urlOption !== undefined) {
if (urlOption.charAt(urlOption.length - 1) === '/') {
url = urlOption + 'browse/';
} else {
url = urlOption + '/browse/';
}
}
}
function removeSpaces(string) {
'use strict';
while (string.charAt(string.length - 1) === ' ') {
string = string.slice(0, string.length - 1);
}
if (string.charAt(0) === ' ') {
var temp = string.split(' ');
string = temp[temp.length - 1];
}
return string;
}
function removeSkypeFormatting(string) {
'use strict';
if (string.charAt(0) === '[') {
var temp = string.split(' ');
string = temp[temp.length - 1];
}
return string;
}
function openWindow() {
'use strict';
window.open(url + key);
}
function openIssue() {
'use strict';
chrome.storage.sync.get(function (item) {
var urlOption = item.savedUrl;
key = document.getElementById('key').value;
setUrl(urlOption);
key = removeSpaces(key);
key = removeSkypeFormatting(key);
if (key === '') {
returnError('Please insert key', 'key');
} else if (url === undefined) {
returnError('Please define URL in Options', 'key');
} else {
openWindow();
}
});
}
var enter = 13;
function inputKeyListener(e) {
'use strict';
if (e.keyCode === enter) {
openIssue();
}
}
function listenInputKey(inputKey) {
'use strict';
if (inputKey.addEventListener) {
inputKey.addEventListener('keydown', inputKeyListener, false);
} else if (inputKey.attachEvent) {
inputKey.attachEvent('keydown', inputKeyListener);
}
}
function listenKeys() {
'use strict';
listenInputKey(document.getElementById('key'));
}
if (window.addEventListener) {
window.addEventListener('load', listenKeys, false);
} else if (window.attachEvent) {
window.attachEvent('onload', listenKeys);
} else {
document.addEventListener('load', listenKeys, false);
}
\ No newline at end of file
// generated by xUnit Wed Oct 08 2014 16:15:01 GMT+0300 (FLE Daylight Time)
// jasmine unit test for openIssue.js
// brackets-xunit: includes=openIssue.js
/*global describe, it, expect, setErrorText, colorBorderToRed, returnError, setUrl, removeSpaces, removeSkypeFormatting, openWindow, openIssue, inputKeyListener, listenInputKey, listenKeys */
describe("test setUrl(urlOption)", function () {
"use strict";
it("setUrl(urlOption) === ?", function () {
var urlOption = "http://example.com";
var url;
setUrl(urlOption);
expect(url).toEqual("http://example.com/browse/");
});
});
describe("test removeSpaces(string), first 1 space", function () {
"use strict";
var string = " string";
it("removeSpaces(string) === ?", function () {
expect(removeSpaces(string)).toEqual("string");
});
});
describe("test removeSpaces(string), first 3 spaces", function () {
"use strict";
var string = " string";
it("removeSpaces(string) === ?", function () {
expect(removeSpaces(string)).toEqual("string");
});
});
describe("test removeSpaces(string), last 1 space", function () {
"use strict";
var string = "string ";
it("removeSpaces(string) === ?", function () {
expect(removeSpaces(string)).toEqual("string");
});
});
describe("test removeSpaces(string), last 4 space", function () {
"use strict";
var string = "string ";
it("removeSpaces(string) === ?", function () {
expect(removeSpaces(string)).toEqual("string");
});
});
describe("test removeSpaces(string), without spaces", function () {
"use strict";
var string = "string";
it("removeSpaces(string) === ?", function () {
expect(removeSpaces(string)).toEqual("string");
});
});
describe("test removeSpaces(string), first and last 1 space", function () {
"use strict";
var string = " string ";
it("removeSpaces(string) === ?", function () {
expect(removeSpaces(string)).toEqual("string");
});
});
describe("test removeSpaces(string), first and last 2 spaces", function () {
"use strict";
var string = " string ";
it("removeSpaces(string) === ?", function () {
expect(removeSpaces(string)).toEqual("string");
});
});
describe("test removeSkypeFormatting(string)", function () {
"use strict";
var string = "[14:04:47] Irina Ivanova: ISSUE-555";
it("removeSkypeFormatting(string) === ?", function () {
expect(removeSkypeFormatting(string)).toEqual("ISSUE-555");
});
});
\ No newline at end of file
This diff is collapsed.
This diff is collapsed.
body { background-color: #eeeeee; padding: 0; margin: 5px; overflow-y: scroll; }
#HTMLReporter { font-size: 11px; font-family: Monaco, "Lucida Console", monospace; line-height: 14px; color: #333333; }
#HTMLReporter a { text-decoration: none; }
#HTMLReporter a:hover { text-decoration: underline; }
#HTMLReporter p, #HTMLReporter h1, #HTMLReporter h2, #HTMLReporter h3, #HTMLReporter h4, #HTMLReporter h5, #HTMLReporter h6 { margin: 0; line-height: 14px; }
#HTMLReporter .banner, #HTMLReporter .symbolSummary, #HTMLReporter .summary, #HTMLReporter .resultMessage, #HTMLReporter .specDetail .description, #HTMLReporter .alert .bar, #HTMLReporter .stackTrace { padding-left: 9px; padding-right: 9px; }
#HTMLReporter #jasmine_content { position: fixed; right: 100%; }
#HTMLReporter .version { color: #aaaaaa; }
#HTMLReporter .banner { margin-top: 14px; }
#HTMLReporter .duration { color: #aaaaaa; float: right; }
#HTMLReporter .symbolSummary { overflow: hidden; *zoom: 1; margin: 14px 0; }
#HTMLReporter .symbolSummary li { display: block; float: left; height: 7px; width: 14px; margin-bottom: 7px; font-size: 16px; }
#HTMLReporter .symbolSummary li.passed { font-size: 14px; }
#HTMLReporter .symbolSummary li.passed:before { color: #5e7d00; content: "\02022"; }
#HTMLReporter .symbolSummary li.failed { line-height: 9px; }
#HTMLReporter .symbolSummary li.failed:before { color: #b03911; content: "x"; font-weight: bold; margin-left: -1px; }
#HTMLReporter .symbolSummary li.skipped { font-size: 14px; }
#HTMLReporter .symbolSummary li.skipped:before { color: #bababa; content: "\02022"; }
#HTMLReporter .symbolSummary li.pending { line-height: 11px; }
#HTMLReporter .symbolSummary li.pending:before { color: #aaaaaa; content: "-"; }
#HTMLReporter .exceptions { color: #fff; float: right; margin-top: 5px; margin-right: 5px; }
#HTMLReporter .bar { line-height: 28px; font-size: 14px; display: block; color: #eee; }
#HTMLReporter .runningAlert { background-color: #666666; }
#HTMLReporter .skippedAlert { background-color: #aaaaaa; }
#HTMLReporter .skippedAlert:first-child { background-color: #333333; }
#HTMLReporter .skippedAlert:hover { text-decoration: none; color: white; text-decoration: underline; }
#HTMLReporter .passingAlert { background-color: #a6b779; }
#HTMLReporter .passingAlert:first-child { background-color: #5e7d00; }
#HTMLReporter .failingAlert { background-color: #cf867e; }
#HTMLReporter .failingAlert:first-child { background-color: #b03911; }
#HTMLReporter .results { margin-top: 14px; }
#HTMLReporter #details { display: none; }
#HTMLReporter .resultsMenu, #HTMLReporter .resultsMenu a { background-color: #fff; color: #333333; }
#HTMLReporter.showDetails .summaryMenuItem { font-weight: normal; text-decoration: inherit; }
#HTMLReporter.showDetails .summaryMenuItem:hover { text-decoration: underline; }
#HTMLReporter.showDetails .detailsMenuItem { font-weight: bold; text-decoration: underline; }
#HTMLReporter.showDetails .summary { display: none; }
#HTMLReporter.showDetails #details { display: block; }
#HTMLReporter .summaryMenuItem { font-weight: bold; text-decoration: underline; }
#HTMLReporter .summary { margin-top: 14px; }
#HTMLReporter .summary .suite .suite, #HTMLReporter .summary .specSummary { margin-left: 14px; }
#HTMLReporter .summary .specSummary.passed a { color: #5e7d00; }
#HTMLReporter .summary .specSummary.failed a { color: #b03911; }
#HTMLReporter .description + .suite { margin-top: 0; }
#HTMLReporter .suite { margin-top: 14px; }
#HTMLReporter .suite a { color: #333333; }
#HTMLReporter #details .specDetail { margin-bottom: 28px; }
#HTMLReporter #details .specDetail .description { display: block; color: white; background-color: #b03911; }
#HTMLReporter .resultMessage { padding-top: 14px; color: #333333; }
#HTMLReporter .resultMessage span.result { display: block; }
#HTMLReporter .stackTrace { margin: 5px 0 0 0; max-height: 224px; overflow: auto; line-height: 18px; color: #666666; border: 1px solid #ddd; background: white; white-space: pre; }
#TrivialReporter { padding: 8px 13px; position: absolute; top: 0; bottom: 0; left: 0; right: 0; overflow-y: scroll; background-color: white; font-family: "Helvetica Neue Light", "Lucida Grande", "Calibri", "Arial", sans-serif; /*.resultMessage {*/ /*white-space: pre;*/ /*}*/ }
#TrivialReporter a:visited, #TrivialReporter a { color: #303; }
#TrivialReporter a:hover, #TrivialReporter a:active { color: blue; }
#TrivialReporter .run_spec { float: right; padding-right: 5px; font-size: .8em; text-decoration: none; }
#TrivialReporter .banner { color: #303; background-color: #fef; padding: 5px; }
#TrivialReporter .logo { float: left; font-size: 1.1em; padding-left: 5px; }
#TrivialReporter .logo .version { font-size: .6em; padding-left: 1em; }
#TrivialReporter .runner.running { background-color: yellow; }
#TrivialReporter .options { text-align: right; font-size: .8em; }
#TrivialReporter .suite { border: 1px outset gray; margin: 5px 0; padding-left: 1em; }
#TrivialReporter .suite .suite { margin: 5px; }
#TrivialReporter .suite.passed { background-color: #dfd; }
#TrivialReporter .suite.failed { background-color: #fdd; }
#TrivialReporter .spec { margin: 5px; padding-left: 1em; clear: both; }
#TrivialReporter .spec.failed, #TrivialReporter .spec.passed, #TrivialReporter .spec.skipped { padding-bottom: 5px; border: 1px solid gray; }
#TrivialReporter .spec.failed { background-color: #fbb; border-color: red; }
#TrivialReporter .spec.passed { background-color: #bfb; border-color: green; }
#TrivialReporter .spec.skipped { background-color: #bbb; }
#TrivialReporter .messages { border-left: 1px dashed gray; padding-left: 1em; padding-right: 1em; }
#TrivialReporter .passed { background-color: #cfc; display: none; }
#TrivialReporter .failed { background-color: #fbb; }
#TrivialReporter .skipped { color: #777; background-color: #eee; display: none; }
#TrivialReporter .resultMessage span.result { display: block; line-height: 2em; color: black; }
#TrivialReporter .resultMessage .mismatch { color: black; }
#TrivialReporter .stackTrace { white-space: pre; font-size: .8em; margin-left: 10px; max-height: 5em; overflow: auto; border: 1px inset red; padding: 1em; background: #eef; }
#TrivialReporter .finished-at { padding-left: 1em; font-size: .6em; }
#TrivialReporter.show-passed .passed, #TrivialReporter.show-skipped .skipped { display: block; }
#TrivialReporter #jasmine_content { position: fixed; right: 100%; }
#TrivialReporter .runner { border: 1px solid gray; display: block; margin: 5px 0; padding: 2px 0 2px 10px; }
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Jasmine Test - openIssue.spec.js</title>
<link rel="stylesheet" type="text/css" href="jasmine.css">
<script type="text/javascript" src="jasmine.js"></script>
<script type="text/javascript" src="jasmine-html.js"></script>
<script type="text/javascript" src="jasmineCompleteReporter.js"></script>
<script src="jquery.js"></script>
<script src="C:/Users/irina/GitHub/JIRA-Issue-Opener/js/openIssue.js?u=1412774978250"></script>
</head>
<body>
<script type="text/javascript">
// generated by xUnit Wed Oct 08 2014 16:15:01 GMT+0300 (FLE Daylight Time)
// jasmine unit test for openIssue.js
// brackets-xunit: includes=openIssue.js
/*global describe, it, expect, setErrorText, colorBorderToRed, returnError, setUrl, removeSpaces, removeSkypeFormatting, openWindow, openIssue, inputKeyListener, listenInputKey, listenKeys */
describe("test setUrl(urlOption)", function () {
"use strict";
it("setUrl(urlOption) === ?", function () {
var urlOption = "http://example.com";
var url;
setUrl(urlOption);
expect(url).toEqual("http://example.com/browse/");
});
});
describe("test removeSpaces(string), first 1 space", function () {
"use strict";
var string = " string";
it("removeSpaces(string) === ?", function () {
expect(removeSpaces(string)).toEqual("string");
});
});
describe("test removeSpaces(string), first 3 spaces", function () {
"use strict";
var string = " string";
it("removeSpaces(string) === ?", function () {
expect(removeSpaces(string)).toEqual("string");
});
});
describe("test removeSpaces(string), last 1 space", function () {
"use strict";
var string = "string ";
it("removeSpaces(string) === ?", function () {
expect(removeSpaces(string)).toEqual("string");
});
});
describe("test removeSpaces(string), last 4 space", function () {
"use strict";
var string = "string ";
it("removeSpaces(string) === ?", function () {
expect(removeSpaces(string)).toEqual("string");
});
});
describe("test removeSpaces(string), without spaces", function () {
"use strict";
var string = "string";
it("removeSpaces(string) === ?", function () {
expect(removeSpaces(string)).toEqual("string");
});
});
describe("test removeSpaces(string), first and last 1 space", function () {
"use strict";
var string = " string ";
it("removeSpaces(string) === ?", function () {
expect(removeSpaces(string)).toEqual("string");
});
});
describe("test removeSpaces(string), first and last 2 spaces", function () {
"use strict";
var string = " string ";
it("removeSpaces(string) === ?", function () {
expect(removeSpaces(string)).toEqual("string");
});
});
describe("test removeSkypeFormatting(string)", function () {
"use strict";
var string = "[14:04:47] Irina Ivanova: ISSUE-555";
it("removeSkypeFormatting(string) === ?", function () {
expect(removeSkypeFormatting(string)).toEqual("ISSUE-555");
});
});
var myParent = window.parent;
var jasmineEnv = jasmine.getEnv();
jasmineEnv.updateInterval = 1000;
var htmlReporter = new jasmine.HtmlReporter();
var reportRunnerResults = htmlReporter.reportRunnerResults;
htmlReporter.reportRunnerResults = function(runner) {
reportRunnerResults(runner);
var specs = runner.specs();
var specResults;
var assertionCount = {total: 0, passed: 0, failed: 0};
var result = {};
for (var i = 0; i < specs.length; ++i) {
if (this.specFilter(specs[i])) {
specResults = specs[i].results();
assertionCount.total += specResults.totalCount;
assertionCount.passed += specResults.passedCount;
assertionCount.failed += specResults.failedCount;
}
}
if (console && console.log) {
console.log('Total: ' + assertionCount.total);
console.log('Passed: ' + assertionCount.passed);
console.log('Failed: ' + assertionCount.failed);
}
if (assertionCount.failed) {
result.status = "failed";
result.message = assertionCount.failed + " failures";
} else {
result.status = "passed";
result.message = "Success! " + assertionCount.passed + " passed";
}
if(myParent.reportComplete) {
console.log("myParent.reportComplete", result);
myParent.reportComplete(result);
}
var totals = document.querySelectorAll(".grand-total .rs");
if(myParent.coverageComplete) {
myParent.coverageComplete({
message: totals && totals[0] ? totals[0].innerHTML + " coverage" : "No coverage"
});
}
};
jasmineEnv.addReporter(htmlReporter);
jasmineEnv.specFilter = function(spec) {
return htmlReporter.specFilter(spec);
};
var currentWindowOnload = window.onload;
window.onload = function() {
if (currentWindowOnload) {
currentWindowOnload();
}
execJasmine();
};
function execJasmine() {
var oldCallback = jasmineEnv.currentRunner().finishCallback;
jasmineEnv.currentRunner().finishCallback = function () {
oldCallback.apply(this, arguments);
console.log(this, arguments);
htmlReporter.reportRunnerResults();
};
jasmineEnv.execute();
}
</script>
</body>
</html>
This diff is collapsed.
/*
Copyright (c) 2008-2013 Pivotal Labs
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
function getJasmineRequireObj() {
if (typeof module !== "undefined" && module.exports) {
return exports;
} else {
window.jasmineRequire = window.jasmineRequire || {};
return window.jasmineRequire;
}
}
getJasmineRequireObj().console = function(jRequire, j$) {
j$.ConsoleReporter = jRequire.ConsoleReporter();
};
getJasmineRequireObj().ConsoleReporter = function() {
var noopTimer = {
start: function(){},
elapsed: function(){ return 0; }
};
function ConsoleReporter(options) {
var print = options.print,
showColors = options.showColors || false,
onComplete = options.onComplete || function() {},
timer = options.timer || noopTimer,
specCount,
failureCount,
failedSpecs = [],
pendingCount,
ansi = {
green: '\033[32m',
red: '\033[31m',
yellow: '\033[33m',
none: '\033[0m'
};
this.jasmineStarted = function() {
specCount = 0;
failureCount = 0;
pendingCount = 0;