Replace ZeroClipboard with clipboard.js. Fixes #32.

This commit is contained in:
Tom Slominski
2016-07-24 17:25:25 +01:00
parent fa5bd1b253
commit 450de0ebf4
12 changed files with 184 additions and 74 deletions

View File

@@ -53,3 +53,5 @@ Licensing
Just like YOURLS, Infinity Squared is licensed under the MIT license. Basically, you can do whatever you want with it as long as you give attribution wherever you use it. There is no guarantee that this software will work.
You can find the full license in the root directory of Infinity Squared, under LICENSE.md.
Clipboard.js is also licensed under the MIT license.

View File

@@ -20,35 +20,14 @@
<?php global $dependencies; ?>
<?php if ( in_array( 'ZeroClipboard', $dependencies ) ) { ?>
<!-- ZeroClipboard is MIT licensed -->
<script type="text/javascript" src="public/ZeroClipboard/ZeroClipboard.min.js"></script>
<script>
ZeroClipboard.config({
swfPath: "public/ZeroClipboard/ZeroClipboard.swf"
});
var clipboardClient = new ZeroClipboard( document.getElementsByClassName("copy-button") );
var copied = "<?php yourls_e( 'Copied!', 'isq_translation'); ?>";
clipboardClient.on( 'aftercopy', function(event) {
event.target.innerHTML = copied;
} );
</script>
<?php if ( in_array( 'clipboard.js', $dependencies ) ) { ?>
<script src="public/js/clipboard.min.js"></script>
<script src="public/js/app.js"></script>
<?php }
if ( in_array( 'reCAPTCHA', $dependencies ) ) { ?>
<script src='https://www.google.com/recaptcha/api.js'></script>
<script src="https://www.google.com/recaptcha/api.js"></script>
<?php } ?>
<!-- Delay loading of transitions until page is fully loaded -->
<script>
window.addEventListener('load',function load() {
window.removeEventListener('load', load, false);
document.body.classList.remove('load');
},false);
</script>
</body>
</html>

View File

@@ -6,7 +6,7 @@ $title = isset( $_REQUEST['title'] ) ? yourls_sanitize_title( $_REQUEST['title
?>
<div class="content">
<div class="content index">
<h2><?php yourls_e( 'Enter a new URL to shorten', 'isq_translation'); ?></h2>
<form method="post" action="result.php" class="newurl" novalidate>
<div class="form-item full-width">
@@ -16,7 +16,6 @@ $title = isset( $_REQUEST['title'] ) ? yourls_sanitize_title( $_REQUEST['title
</div>
<div class="halves">
<div class="form-item half-width left">
<p><label for="keyword" class="primary"><?php yourls_e( 'Custom keyword', 'isq_translation'); ?></label></p>
<p><label for="keyword" class="secondary"><?php yourls_e( 'A keyword replaces the default short string.', 'isq_translation'); ?></label></p>
@@ -28,7 +27,6 @@ $title = isset( $_REQUEST['title'] ) ? yourls_sanitize_title( $_REQUEST['title
<p><label for="title" class="secondary"><?php yourls_e( 'Optional title used when sharing a link from YOURLS using social sharers.', 'isq_translation'); ?></label></p>
<input type="text" id="title" name="title" value="<?php echo($title); ?>">
</div>
</div>
<?php

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -8,7 +8,6 @@
ISQ::$general = array(
'name' => 'URL shortener', // The name of your URL shortener
'qr' => TRUE, // Do you want to display a QR code?
'clipboard' => 1, // Do you want to enable zeroClipboard? (uses flash)
'customstyle' => TRUE // Do you want to enable the custom stylesheet, found in public/custom.css?
);

12
public/images/clippy.svg Executable file
View File

@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg width="14px" height="16px" viewBox="0 0 14 16" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Generator: Sketch 3.8.3 (29802) - http://www.bohemiancoding.com/sketch -->
<title>clippy</title>
<desc>Created with Sketch.</desc>
<defs></defs>
<g id="Octicons" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="clippy" fill="#000000">
<path d="M2,13 L6,13 L6,14 L2,14 L2,13 L2,13 Z M7,7 L2,7 L2,8 L7,8 L7,7 L7,7 Z M9,10 L9,8 L6,11 L9,14 L9,12 L14,12 L14,10 L9,10 L9,10 Z M4.5,9 L2,9 L2,10 L4.5,10 L4.5,9 L4.5,9 Z M2,12 L4.5,12 L4.5,11 L2,11 L2,12 L2,12 Z M11,13 L12,13 L12,15 C11.98,15.28 11.89,15.52 11.7,15.7 C11.51,15.88 11.28,15.98 11,16 L1,16 C0.45,16 0,15.55 0,15 L0,4 C0,3.45 0.45,3 1,3 L4,3 C4,1.89 4.89,1 6,1 C7.11,1 8,1.89 8,3 L11,3 C11.55,3 12,3.45 12,4 L12,9 L11,9 L11,6 L1,6 L1,15 L11,15 L11,13 L11,13 Z M2,5 L10,5 C10,4.45 9.55,4 9,4 L8,4 C7.45,4 7,3.55 7,3 C7,2.45 6.55,2 6,2 C5.45,2 5,2.45 5,3 C5,3.55 4.55,4 4,4 L3,4 C2.45,4 2,4.45 2,5 L2,5 Z" id="Shape"></path>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

50
public/js/app.js Normal file
View File

@@ -0,0 +1,50 @@
function filterNodeListById( nodeList, id ) {
var elements = Array.prototype.slice.call( nodeList );
for (var i = elements.length - 1; i >= 0; i--) {
if( elements[i].id == id ) {
return elements[i];
}
}
}
// Clipboard.js
if( document.querySelectorAll( '.copy-button' ).length > 0 ) {
var clipboard = new Clipboard( '.copy-button' );
var clipboardTimeout = 2000;
clipboard.on( 'success', function( event ) {
var errorElement = filterNodeListById( event.trigger.parentNode.childNodes, 'copy-success' );
errorElement.className += " visible";
window.setTimeout( function() {
errorElement.className = errorElement.className.replace(/\bvisible\b/,'');
}, clipboardTimeout );
} );
clipboard.on( 'error', function( event ) {
var errorElement = filterNodeListById( event.trigger.parentNode.childNodes, 'copy-error' );
var osClass;
if( /iPhone|iPad/i.test(navigator.userAgent) ) {
osClass = 'mobile';
} else if ( /Mac/i.test(navigator.userAgent) ) {
osClass = 'macos';
} else if ( /Windows/i.test(navigator.userAgent) || /X11/i.test(navigator.userAgent) ) {
osClass = 'pc';
} else {
osClass = 'other';
}
errorElement.className += " visible " + osClass;
window.setTimeout( function() {
errorElement.className = errorElement.className.replace(/\bvisible\b/,'');
}, clipboardTimeout );
} );
}

7
public/js/clipboard.min.js vendored Executable file

File diff suppressed because one or more lines are too long

View File

@@ -200,6 +200,7 @@ input:not([type=submit]):not([type=file]) {
transition: box-shadow 0.5s, border 0.5s;
-webkit-appearance: none;
border-radius: 0;
height: 45px;
}
.g-recaptcha {
@@ -232,7 +233,7 @@ input[type=submit] {
display: inline-block;
}
.button:hover, .zeroclipboard-is-hover {
.button:hover {
background: #E2E2E2;
}
@@ -253,12 +254,62 @@ input[type=submit] {
font-weight: bold;
}
.copy-button {
margin-top: 2px;
.input-with-copy {
position: relative;
}
.copy-button:focus {
outline: none;
.input-with-copy input:not([type=submit]):not([type=file]) {
width: calc( 100% - 45px );
}
.input-with-copy .copy-button {
position: absolute;
right: 0;
top: 5px;
height: 45px;
width: 45px;
border-left: 0;
}
.copy-message {
position: absolute;
top: 6px;
left: 1px;
height: 43px;
line-height: 43px;
width: calc( 100% - 47px );
text-align: center;
background: rgba(0, 0, 0, 0.7);
transition: opacity 0.3s, visibility 0.3s;
color: white;
opacity: 0;
visibility: hidden;
-webkit-transform: translate3d(0, 0, 0); // WebKit animation fix
}
.copy-message.visible {
opacity: 1;
visibility: visible;
}
.copy-message .os {
display: none;
}
.copy-message.error.macos .macos {
display: block;
}
.copy-message.error.pc .pc {
display: block;
}
.copy-message.error.mobile .mobile {
display: block;
}
.copy-message.error.other .other {
display: block;
}
.social-button {

View File

@@ -89,13 +89,11 @@ $encoded_shorturl = urlencode($shorturl);
$encoded_title = urlencode($title);
// Add dependencies
if ( ISQ::$general['clipboard'] ) {
$dependencies[] = 'ZeroClipboard';
};
$dependencies[] = 'clipboard.js';
?>
<div class="content">
<div class="content result">
<!-- Error reporting -->
<?php isset( $error ) ? $error : ''; ?>
@@ -105,24 +103,49 @@ if ( ISQ::$general['clipboard'] ) {
<div class="output">
<div class="form-item full-width">
<label for="longurl" class="primary"><?php yourls_e( 'Original URL', 'isq_translation'); ?></label>
<div class="input-with-copy">
<input type="text" name="longurl" id="longurl" onclick="this.select();" onload="this.select();" value="<?php echo $url; ?>">
<?php if ( ISQ::$general['clipboard'] ) { echo '<button data-clipboard-target="longurl" class="desktop-only copy-button button">' . yourls__( 'Copy to clipboard', 'isq_translation' ) . '</button>'; } ?>
<button data-clipboard-target="#longurl" class="copy-button button" title="<?php yourls_e( 'Copy to clipboard', 'isq_translation' ); ?>"><img src="public/images/clippy.svg"></button>
<div class="copy-message success" id="copy-success"><?php yourls_e( 'Copied to clipboard', 'isq_translation' ); ?></div>
<div class="copy-message error" id="copy-error">
<span class="os macos"><?php yourls_e( 'Press ⌘+C to copy', 'isq_translation' ); ?></span>
<span class="os pc"><?php yourls_e( 'Press Ctrl+C to copy', 'isq_translation' ); ?></span>
<span class="os mobile"><?php yourls_e( 'Tap copy', 'isq_translation' ); ?></span>
<span class="os other"><?php yourls_e( 'Failed to copy', 'isq_translation' ); ?></span>
</div>
</div>
</div>
<div class="halves">
<div class="form-item half-width left">
<label for="shorturl" class="primary"><?php yourls_e( 'Short URL', 'isq_translation'); ?></label>
<div class="input-with-copy">
<input type="text" name="shorturl" id="shorturl" onclick="this.select();" value="<?php echo $shorturl; ?>">
<?php if ( ISQ::$general['clipboard'] ) { echo '<button data-clipboard-target="shorturl" class="desktop-only copy-button button">' . yourls__( 'Copy to clipboard', 'isq_translation' ) . '</button>'; } ?>
<button data-clipboard-target="#shorturl" class="copy-button button" title="<?php yourls_e( 'Copy to clipboard', 'isq_translation' ); ?>"><img src="public/images/clippy.svg"></button>
<div class="copy-message success" id="copy-success"><?php yourls_e( 'Copied to clipboard', 'isq_translation' ); ?></div>
<div class="copy-message error" id="copy-error">
<span class="os macos"><?php yourls_e( 'Press ⌘+C to copy', 'isq_translation' ); ?></span>
<span class="os pc"><?php yourls_e( 'Press Ctrl+C to copy', 'isq_translation' ); ?></span>
<span class="os mobile"><?php yourls_e( 'Tap copy', 'isq_translation' ); ?></span>
<span class="os other"><?php yourls_e( 'Failed to copy', 'isq_translation' ); ?></span>
</div>
</div>
</div>
<div class="form-item half-width right">
<label for="stats" class="primary"><?php /* translators: This is short for statistics */ yourls_e( 'Stats', 'isq_translation'); ?></label>
<div class="input-with-copy">
<input type="text" name="stats" id="stats" onclick="this.select();" value="<?php echo $shorturl . '+'; ?>" id="stats-copy">
<?php if ( ISQ::$general['clipboard'] ) { echo '<button data-clipboard-target="stats" class="desktop-only copy-button button">' . yourls__( 'Copy to clipboard', 'isq_translation' ) . '</button>'; } ?>
<button data-clipboard-target="#stats" class="copy-button button" title="<?php yourls_e( 'Copy to clipboard', 'isq_translation' ); ?>"><img src="public/images/clippy.svg"></button>
<div class="copy-message success" id="copy-success"><?php yourls_e( 'Copied to clipboard', 'isq_translation' ); ?></div>
<div class="copy-message error" id="copy-error">
<span class="os macos"><?php yourls_e( 'Press ⌘+C to copy', 'isq_translation' ); ?></span>
<span class="os pc"><?php yourls_e( 'Press Ctrl+C to copy', 'isq_translation' ); ?></span>
<span class="os mobile"><?php yourls_e( 'Tap copy', 'isq_translation' ); ?></span>
<span class="os other"><?php yourls_e( 'Failed to copy', 'isq_translation' ); ?></span>
</div>
</div>
</div>
</div>
<p class="desktop-only"><?php yourls_e( 'Click on a link and press Ctrl+C to quickly copy it.', 'isq_translation'); ?></p>