This commit is contained in:
Dym Sohin 2023-10-04 20:39:05 +02:00
commit cb344b8069
5 changed files with 541 additions and 0 deletions

45
index.html Normal file
View File

@ -0,0 +1,45 @@
<!DOCTYPE html>
<html manifest='cache.manifest'>
<head><title>Git.io</title>
<meta charset='utf-8'>
<meta name='description' content='git.io browser extension with support for custom URLs and shrt-history'>
<meta name='keywords' content='github, git.io'>
<meta name='apple-mobile-web-app-capable' content='yes'>
<meta name='apple-mobile-web-app-status-bar-style' content='black'>
<meta name='viewport' content='width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no'>
<link rel='icon' type='image/png' sizes='512x512' href='icon.png'>
<link rel='icon' type='image/png' sizes='128x128' href='favicon.png'>
<link rel='stylesheet' href='./style.css'>
<script type='text/javascript' src='./script.js'></script>
</head>
<body>
<section>
<label for='full-url'>GitHub</label>
<input id='full-url' type='text' placeholder='full url'>
</section>
<section>
<label for='shortened-url'>Git.io</label>
<input id='shortened-url' type='text' placeholder='(custom shortener)'>
<button id='action-button'>shrt!</button>
</section>
<ul id='notifications'>
<li><span id='message'>Enter the shortener (optional) and click “shrt!”<span></li>
</ul>
<ul id='recent-links'></ul>
<ul id='show-all-recent-links' title='Show all recent links'>
<li></li>
</ul>
<ul id='clear-list' title='Clear the list'>
<li>clear list</li>
</ul>
</body>
</html>

11
manifest.webapp Normal file
View File

@ -0,0 +1,11 @@
{ "name": "Git.io Addon"
, "description": "git.io browser extension with support for custom URLs and shrt-history"
, "launch_path": "./"
, "default_locale": "en"
, "icons":
{ "500": "icon.png" }
, "developer":
{ "name": "Dym Sohin"
, "url": "https://dym.sh"
}
}

BIN
screenshot.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

252
script.js Normal file
View File

@ -0,0 +1,252 @@
var GitIO = function ( )
{
var API_ENDPOINT = 'http://git.io/'
this.invoke = function ( command, params, response_callback )
{
if( 'generate' == command )
{ requestForShortenUrl
( params.url
, params.code
, function ( data )
{ response_callback( data ) }
)
}
}
var requestForShortenUrl = function ( url, code, callback )
{
var xhr = new XMLHttpRequest( )
var form_data = new FormData( )
form_data.append( 'url', url )
if( code )
{ form_data.append( 'code', code ) }
xhr.onload = function ( e )
{
if( 201 == this.status )
{ callback
({ 'status': 'OK'
, 'shortened_url' : this.getResponseHeader( 'Location' )
})
}
else
{ callback
({ 'status' : 'Error'
, 'error' :
{ 'code' : this.status
, 'message' : this.responseText
}
})
}
}
xhr.open( 'POST', API_ENDPOINT, true )
xhr.send( form_data )
}
}
chrome.extension.onRequest.addListener
( function ( request, sender, sendResponse )
{ GitIO.invoke( request.command, request.params, sendResponse ) }
)
localStorage.getItem( 'notFirstRun', function ( arr )
{
if( arr['notFirstRun'] ) return
var shrtList =
{ 'http://git.io/help' : 'https://github.com/blog/985-git-io-github-url-shortener'
, 'http://git.io/nn' : 'https://github.com/noformnocontent'
, 'http://git.io/chrome' : 'https://github.com/noformnocontent/git-io-chrome'
}
localStorage.setItem( 'shrtList', shrtList )
localStorage.setItem( 'notFirstRun', true )
})
var shrt_field = document.getElementById( 'shortened-url' )
, url_field = document.getElementById( 'full-url' )
, notifications = document.getElementById( 'notifications' )
, message_field = document.getElementById( 'message' )
, action_button = document.getElementById( 'action-button' )
, show_all_recent_links = document.getElementById( 'show-all-recent-links' )
, clear_list = document.getElementById( 'clear-list' )
, recent_links = document.getElementById( 'recent-links' )
, lis = recent_links.getElementsByTagName( 'li' )
var shrtLink = function ( )
{ getShortenedUrl( ) }
action_button.addEventListener( 'click', shrtLink )
localStorage.getItem( function ( arr )
{ for( var k in arr )
{ createShrtListElement( k, arr[k]) }
})
var setMessage = function ( message )
{ message_field.innerHTML = message }
var copyResultToClipboard = function ( field )
{
field.select( )
document.execCommand( 'Copy' )
notifications.classList.remove( 'error' )
notifications.classList.add( 'done' )
setMessage( 'Link is copied to the clipboard.' )
}
var bindBtnToCoopy = function ( )
{
action_button.removeEventListener( 'click', shrtLink, false )
action_button.addEventListener( 'click', function ( )
{ copyResultToClipboard( shrt_field ) })
action_button.innerHTML = 'cpy!'
action_button.classList.remove( 'error' )
action_button.classList.add( 'done' )
notifications.classList.remove( 'error' )
notifications.classList.add( 'done' )
setMessage( 'You can now copy the link by clicking “cpy!”'
+ ' It will also stay in your shrt-list if you ever need it again.'
)
}
var createShrtListElement = function ( shrt, fullUrl, flashListsElement )
{
if( !/^https?:\/\/git\.io\/.+/.test( shrt ) ) return
var listElement = document.createElement( 'li' )
, listInput = document.createElement( 'input' )
, listVisit = document.createElement( 'a' )
, listCopy = document.createElement( 'a' )
listInput.value = shrt
listInput.type = 'text'
listInput.readOnly = true
listVisit.href = shrt
listVisit.target = '_new'
listVisit.title = 'Open link in new tab'
listVisit.appendChild( document.createTextNode( '' ))
listCopy.href = '#copy'
listCopy.title = 'Copy link to clipboard'
listCopy.appendChild( document.createTextNode( '' ))
listCopy.addEventListener( 'click', function ( e )
{
copyResultToClipboard
( e.currentTarget.parentNode
.getElementsByTagName( 'input' )[0]
)
e.preventDefault( )
})
listElement.title = fullUrl
listElement.appendChild( listInput )
listElement.appendChild( listVisit )
listElement.appendChild( listCopy )
if( flashListsElement )
{ listElement.classList.add( 'current' ) }
recent_links.insertBefore
( listElement, recent_links.firstChild )
testShrtListLength( )
}
var getShortenedUrl = function ( )
{
var request_data =
{ 'command': 'generate'
, 'params':
{ 'url': url_field
, 'code': shrt_field.value
}
}
chrome.extension.sendRequest( request_data, function ( data )
{
if( 'OK' == data.status )
{
// TODO: notice if sent and recived shortened are different
shrt_field.value = data.shortened_url
bindBtnToCoopy( )
localStorage.getItem( data.shortened_url, function ( arr )
{
if( !arr[data.shortened_url] )
{
var urlPair = { }
urlPair[data.shortened_url] = tab.url
localStorage.setItem( urlPair )
}
else
{ // bump to the top and '.current' the one in the list
}
})
}
else if( 'Error' == data.status )
{
action_button.innerHTML = 'rrr!'
action_button.classList.remove( 'done' )
action_button.classList.add( 'error' )
notifications.classList.remove( 'done' )
notifications.classList.add( 'error' )
setMessage( data.error.code + ': ' + data.error.message )
}
else
{
action_button.innerHTML = '??!'
action_button.classList.remove( 'done' )
action_button.classList.add( 'error' )
notifications.classList.remove( 'done' )
notifications.classList.add( 'error' )
setMessage( data.status )
}
})
}
var testShrtListLength = function ( )
{
if( lis.length > 3 )
{
show_all_recent_links.style.display = 'block'
show_all_recent_links.getElementsByTagName( 'li' )[0]
.innerHTML = '▾ show ' + ( lis.length-3 ) + ' more ▾'
show_all_recent_links.addEventListener( 'click', function ( )
{
for( var i = 3; i < lis.length; i++ )
{ lis[i].style.display = 'block' }
show_all_recent_links.style.display = 'none'
clear_list.style.display = 'block'
clear_list.addEventListener( 'click', function ( )
{
while( lis[0] )
{ lis[0].parentNode.removeChild( lis[0]) }
localStorage.clear( )
localStorage.setItem( 'notFirstRun', true )
clear_list.style.display = 'none'
})
})
}
}
chrome.storage.onChanged.addListener( function ( changes, namespace )
{
for( key in changes )
{ if( changes[key].newValue )
{ createShrtListElement( key, changes[key], true ) }
}
})

233
style.css Normal file
View File

@ -0,0 +1,233 @@
* { margin : 0
; padding : 0
; text-rendering : optimizeLegibility
}
@font-face
{ font-family : 'Octicons Regular'
; src : url('octicons.woff') format('woff')
; font-weight : normal
; font-style : normal
}
body
{ font-family : sans-serif
; font-size : 0
; background : #e7eef1
; padding : 15px
; word-break : keep-all
; white-space : nowrap
; margin : 0 auto
; width : 255px
}
label
{ font-size : 14px
; background : linear-gradient(#839ba9, #415b6b)
; border-radius : 3px 0 0 3px
; border-top : solid 1px #313b3d
; border-left : solid 1px #232b2c
; border-bottom : solid 1px #232b2c
; border-right : solid 1px #232b2c
; box-shadow : 0 1px 3px #6a8290 inset
; color : #e7eef1
; padding : 5px 7px 6px 7px
; display : inline-block
; letter-spacing : .075pt
; line-height : 1rem
; width : 37px
; text-align : center
}
label[for='full-url']
{ font-size : 12px }
form
{ display : inline }
section
{ margin-bottom : 15px }
::-webkit-input-placeholder
{ color : #b3bbbe }
::input-placeholder
{ color : #b3bbbe }
#shortened-url
, #full-url
{ background : #f7f9fa
; font-size : 14px
; color : #3b4448
; border-top : solid 1px #49565e
; border-right : 0
; border-bottom : solid 1px #37434c
; border-left : 0
; box-shadow : 0 1px 3px #6a8290 inset
; vertical-align : top
; padding : 3px 5px
; height : 21px
; width : 144px
}
#full-url
{ width : 192px
; border-right : solid 1px #37434c
; border-radius : 0 3px 3px 0
}
button
{ width : 49px
; height : 29px
; font-size : 14px
; line-height : 12px
; background : linear-gradient(#425B6B, #24323B)
; border-radius : 0 3px 3px 0
; border-top : solid 1px #313b3d
; border-left : solid 1px #232b2c
; border-bottom : solid 1px #232b2c
; border-right : solid 1px #232b2c
; box-shadow : 0 1px 0 #5f7886 inset
; vertical-align : top
; color : #fff
; padding : 5px 7px
}
button.done
{ background : linear-gradient(#52a360, #477651) }
button.error
{ background : linear-gradient(#b24142, #803b3d) }
ul
{ width : 255px
; font-size : 14px
; list-style : none
; margin-top : 15px
}
ul li
{ border : solid 1px #839ba9
; border-top : 0
; background : #e7eef1
; text-align : center
; padding : 7px 5px
}
ul li:first-child
{ border-top : solid 1px #839ba9
; border-top-left-radius : 3px
; border-top-right-radius : 3px
}
ul li:last-child
{ border-bottom-left-radius : 3px
; border-bottom-right-radius : 3px
}
#recent-links li
{ display : none
; padding : 0
; text-align : right
; font-size : 0
}
#recent-links li:hover
{ background : #f7f9fa }
#recent-links li input
{ float : left
; font-size : 12px
; width : 158px
; padding : 2px
; background : none
; border : 0
; text-overflow : ellipsis
; color : #839ba9
; margin : 5px 5px
}
#recent-links li:hover input
{ color : #3b4448 }
#recent-links li a
{ font-family : 'Octicons Regular'
; visibility : hidden
; text-decoration : none
; text-align : center
; padding : 3px
; display : inline-block
; color : #3b4448
; font-size : 16px
; height : 24px
; width : 24px
; font-smoothing : antialiased
; line-height : 1.5em
}
#recent-links li:hover a
{ visibility : visible }
#recent-links li a:hover
, #recent-links li a:active
, #recent-links li a:focus
{ background-image : linear-gradient(#5899cc, #3173b4)
; color : #fff
}
section
{ box-shadow : 1px 1px 2px #6a8290
; border-radius : 3px
; width : 255px
}
#recent-links li:first-child
, #recent-links li:nth-child(2)
, #recent-links li:nth-child(3)
{ display : block }
#show-all-recent-links, #clear-list
{ color : #839ba9
; display : none
; cursor : pointer
; font-size : 12px
; line-height : 15px
; margin-top : 0
}
#show-all-recent-links li
{ color : #839ba9
; border-top-left-radius : 0
; border-top-right-radius : 0
; border-top : 0
}
#show-all-recent-links:hover li
{ background : #f7f9fa
; color : #3b4448
}
#clear-list
{ margin-top : 15px }
#clear-list:hover li
{ background-color : #fee1e5
; color : #3b4448
}
#notifications li
{ font-size : 11px
; text-overflow : ellipsis
; word-break : normal
; white-space : normal
; transition-property : background-color
; transition-duration : 0.3s
; background-color : #f7f9fa
}
#notifications.done li
, #recent-links li.current
{ background-color : #e5fae6 }
#notifications.error li
{ background-color : #fee1e5 }