Skip to content

Commit

Permalink
Merge pull request #14 from kiichi/feature/hot-key
Browse files Browse the repository at this point in the history
Hotkey, Local Storage, Notification, and Refactoring
  • Loading branch information
kiichi authored May 17, 2020
2 parents 088e6e1 + d547143 commit 74ec645
Show file tree
Hide file tree
Showing 8 changed files with 221 additions and 141 deletions.
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,11 @@ git clone https://github.com/kiichi/QuickCopyTitleAndURL.git
6. See Cat Icon on Top Right Corner.
7. If you change the code, click reload button to test again.

## Debugging Tips

1. Some of manifest changes requires reloading plugin. Click reload or remove and load unpacked folder again.
2. In order to see console.log, click background page.


## Uploading to app store - Memo for myself

Expand Down
27 changes: 26 additions & 1 deletion src/background.js
Original file line number Diff line number Diff line change
@@ -1 +1,26 @@
// Nothing
'use strict'
// Background Thread
// Note:
// Reload or Uninstall Extension when you change manifest
// Max number of shortcut is 4.
// Debug Console - Open extension > click background page link

/////////////////////////////////////////////////////////////////////
// Globals
let notificationId = "copy-0";

/////////////////////////////////////////////////////////////////////
// Key Listener from manifest
chrome.commands.onCommand.addListener((command)=>{
//console.log(document);
//console.log(command);
chrome.storage.local.get(['dataType'], (result)=>{
let dataType = result.dataType || 'dash';
let dataAction = command; // see manifest shortcut definition
doCopy(dataType,dataAction,(copiedText)=>{
let details = (dataAction === 'all') ? 'All Tabs' : copiedText;
showNotification(dataType, dataAction, details);
});
});
});

123 changes: 123 additions & 0 deletions src/common.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
'use strict'
/////////////////////////////////////////////////////////////////////
// Globals
const Lookup = {
DataTypes: [
{ dataType:"dash", description:"Title - URL" },
{ dataType:"bracket", description:"[Title] URL" },
{ dataType:"newline", description:"in Two Lines" },
{ dataType:"rich", description:"Rich Text Link" },
{ dataType:"html", description:"HTML" },
{ dataType:"md", description:"Markdown" },
{ dataType:"bb", description:"BBCode" },
{ dataType:"title", description:"Title Only" },
{ dataType:"url", description:"URL Only" },
]
};

/////////////////////////////////////////////////////////////////////
function copyToClip(mime, str) {
function listener(e) {
e.clipboardData.setData(mime, str);
e.preventDefault();
}
document.addEventListener("copy", listener);
document.execCommand("copy");
document.removeEventListener("copy", listener);
};

/////////////////////////////////////////////////////////////////////
function isImage(url){
return (url.indexOf('.jpg') > -1 || url.indexOf('.png') > -1);
}

/////////////////////////////////////////////////////////////////////
// dataType - type of data format to copy e.g. "dash" see popup.html data-type attributes
// dataAction - action when it copies: "single" or "all"
// onSuccess - callback after copied. Copied text is in argument
function doCopy(dataType, dataAction, onSuccess){
let options = {currentWindow:true};
if (dataAction == 'single'){
options['active'] = true;
}
let mime = (dataType == 'rich') ? 'text/html': 'text/plain';
let allText = '';
chrome.tabs.query(options, (tabs)=>{
for (let i=0; i<tabs.length; i++){
let txt = 'ERROR - Sorry something went wrong.';
let tab_title = tabs[i].title;
let tab_url = tabs[i].url;
// remove leading "notification counts" that websites have started to add
// For info, watch : https://www.youtube.com/watch?v=bV0QNuhN9fU&t=64s
let matches = tab_title.match(/^(\([0-9]+\) )?(.*)$/);
if (matches) {
tab_title = matches[2];
}
if (dataType === 'dash') {
txt = tab_title + ' - ' + tab_url;
}
else if (dataType == 'bracket') {
txt = '[' + tab_title + '] ' + tab_url;
}
else if (dataType == 'newline') {
txt = tab_title + '\n' + tab_url;
}
else if (dataType == 'html' || dataType == 'rich') {
txt = '<a href="' + tab_url + '">' + tab_title + '</a>';
}
else if (dataType == 'md') {
let prefix = '';
if (isImage(tab_url)){
prefix = '!';
}
txt = prefix + '[' + tab_title + '](' + tab_url + ')';
}
else if (dataType == 'bb') {
if (isImage(tab_url)){
txt = '[img]'+tab_url+'[/img]';
}
else {
txt = '[url='+tab_url+']'+tab_title+'[/url]';
}
}
else if (dataType == 'url') {
txt = tab_url;
}
else if (dataType == 'title') {
txt = tab_title;
}
allText += txt;
if (tabs.length > 1){
allText += (dataType == 'html' || dataType == 'rich') ? '<br/>\n' : '\n';
}
}

copyToClip(mime,allText);
if (onSuccess){
onSuccess(allText);
}
});

// Save the dataType
chrome.storage.local.set({"dataType": dataType},()=>{});
}

/////////////////////////////////////////////////////////////////////
function showNotification(dataType, dataAction, details){
chrome.notifications.clear(notificationId);
notificationId = 'copy-'+(new Date()).getTime();
let copiedType = 'Single Tab';
if (dataAction === 'all'){
copiedType = "All Tabs";
}
let desc = Lookup.DataTypes.find(item=>item.dataType===dataType).description;
let options = {type:"basic",
silent: true,
iconUrl:"icons/icon.png",
title:`Copied ${desc} into your clipboard`,
message:details};

chrome.notifications.create(notificationId, options, (notificationId)=>{
//console.log("notification sent",notificationId,options);
});
}
28 changes: 25 additions & 3 deletions src/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@
"manifest_version": 2,
"name": "Copy Cat - Quick Copy Title and URL",
"description": "Quickly copy the title of page and url into your clipboard!",
"version": "1.4.3",
"version": "1.5.0",
"permissions": [
"tabs",
"clipboardWrite"
"clipboardWrite",
"notifications",
"storage"
],
"browser_action": {
"default_title": "Copy Title and URL",
Expand All @@ -16,5 +18,25 @@
"16": "icons/icon16.png",
"48": "icons/icon48.png",
"128": "icons/icon128.png"
},
"background": {
"scripts": ["common.js","background.js"],
"persistent": false
},
"commands": {
"single": {
"suggested_key": {
"default": "Alt+Shift+C",
"mac": "MacCtrl+Shift+C"
},
"description": "Repeat previous copy"
},
"all": {
"suggested_key": {
"default": "Alt+Shift+A",
"mac": "MacCtrl+Shift+A"
},
"description": "Repeat previous copy for all tabs"
}
}
}
}
71 changes: 11 additions & 60 deletions src/popup.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,82 +5,33 @@
<title>Copy Title and URL</title>
<style>
.container {
width: 200px;
width: 240px;
}

.pure-button {
width: 100%;
font-size: 90% !important;
font-size: 120% !important;
border-radius: 0px !important;
}
.pure-button .check {
font-size: 90% !important;
}

.text-left {
text-align: left !important;
}

#clipboard {
position: absolute;
top: -100;
width: 0px;
height: 0px;
margin: 0px;
padding: 0px;
}

</style>
<link rel="stylesheet" href="pure-min.css" />
<script src="jquery-3.3.1.min.js"></script>
<link rel="stylesheet" href="vendor/pure-min.css" />
<script src="vendor/jquery-3.3.1.min.js"></script>
<script src="common.js"></script>
<script src="popup.js"></script>
</head>

<body>
<div class="container">
<div class="pure-g">
<div class="pure-u-17-24"><button class="pure-button text-left" data-type="dash" data-action="single">Copy Title -
URL</button></div>
<div class="pure-u-7-24"><button class="pure-button" data-type="dash" data-action="all">All Tabs</button></div>
</div>
<div class="pure-g">
<div class="pure-u-17-24"><button class="pure-button text-left" data-type="bracket" data-action="single">Copy
[Title] URL</button></div>
<div class="pure-u-7-24"><button class="pure-button" data-type="bracket" data-action="all">All Tabs</button></div>
</div>
<div class="pure-g">
<div class="pure-u-17-24"><button class="pure-button text-left" data-type="newline" data-action="single">Copy
in Two Lines</button></div>
<div class="pure-u-7-24"><button class="pure-button" data-type="newline" data-action="all">All Tabs</button></div>
</div>
<div class="pure-g">
<div class="pure-u-17-24"><button class="pure-button text-left" data-type="rich" data-action="single">Copy Rich
Text Link</button></div>
<div class="pure-u-7-24"><button class="pure-button" data-type="rich" data-action="all">All Tabs</button></div>
</div>
<div class="pure-g">
<div class="pure-u-17-24"><button class="pure-button text-left" data-type="html" data-action="single">Copy
HTML</button></div>
<div class="pure-u-7-24"><button class="pure-button" data-type="html" data-action="all">All Tabs</button></div>
</div>
<div class="pure-g">
<div class="pure-u-17-24"><button class="pure-button text-left" data-type="md" data-action="single">Copy
Markdown</button></div>
<div class="pure-u-7-24"><button class="pure-button" data-type="md" data-action="all">All Tabs</button></div>
</div>
<div class="pure-g">
<div class="pure-u-17-24"><button class="pure-button text-left" data-type="bb" data-action="single">Copy
BBCode</button></div>
<div class="pure-u-7-24"><button class="pure-button" data-type="bb" data-action="all">All Tabs</button></div>
</div>
<div class="pure-g">
<div class="pure-u-17-24"><button class="pure-button text-left" data-type="title" data-action="single">Copy Title
Only</button></div>
<div class="pure-u-7-24"><button class="pure-button" data-type="title" data-action="all">All Tabs</button></div>
</div>
<div class="pure-g">
<div class="pure-u-17-24"><button class="pure-button text-left" data-type="url" data-action="single">Copy URL
Only</button></div>
<div class="pure-u-7-24"><button class="pure-button" data-type="url" data-action="all">All Tabs</button></div>
</div>
</div>
<textarea id="clipboard"></textarea>
<div id="menu" class="container"></div>
<!-- <div id="settings" class="container"></div> -->
</body>

</html>
Loading

0 comments on commit 74ec645

Please sign in to comment.