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. 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. 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 global $dependencies; ?>
<?php if ( in_array( 'ZeroClipboard', $dependencies ) ) { ?> <?php if ( in_array( 'clipboard.js', $dependencies ) ) { ?>
<!-- ZeroClipboard is MIT licensed --> <script src="public/js/clipboard.min.js"></script>
<script type="text/javascript" src="public/ZeroClipboard/ZeroClipboard.min.js"></script> <script src="public/js/app.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 } <?php }
if ( in_array( 'reCAPTCHA', $dependencies ) ) { ?> 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 } ?> <?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> </body>
</html> </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> <h2><?php yourls_e( 'Enter a new URL to shorten', 'isq_translation'); ?></h2>
<form method="post" action="result.php" class="newurl" novalidate> <form method="post" action="result.php" class="newurl" novalidate>
<div class="form-item full-width"> <div class="form-item full-width">
@@ -16,19 +16,17 @@ $title = isset( $_REQUEST['title'] ) ? yourls_sanitize_title( $_REQUEST['title
</div> </div>
<div class="halves"> <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>
<input type="text" id="keyword" name="keyword" autocorrect="off" autocapitalize="none" value="<?php echo($keyword); ?>">
</div>
<div class="form-item half-width left"> <div class="form-item half-width right">
<p><label for="keyword" class="primary"><?php yourls_e( 'Custom keyword', 'isq_translation'); ?></label></p> <p><label for="title" class="primary"><?php yourls_e( 'Custom title', 'isq_translation'); ?></label></p>
<p><label for="keyword" class="secondary"><?php yourls_e( 'A keyword replaces the default short string.', 'isq_translation'); ?></label></p> <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="keyword" name="keyword" autocorrect="off" autocapitalize="none" value="<?php echo($keyword); ?>"> <input type="text" id="title" name="title" value="<?php echo($title); ?>">
</div> </div>
<div class="form-item half-width right">
<p><label for="title" class="primary"><?php yourls_e( 'Custom title', 'isq_translation'); ?></label></p>
<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> </div>
<?php <?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( ISQ::$general = array(
'name' => 'URL shortener', // The name of your URL shortener 'name' => 'URL shortener', // The name of your URL shortener
'qr' => TRUE, // Do you want to display a QR code? '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? '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; transition: box-shadow 0.5s, border 0.5s;
-webkit-appearance: none; -webkit-appearance: none;
border-radius: 0; border-radius: 0;
height: 45px;
} }
.g-recaptcha { .g-recaptcha {
@@ -232,7 +233,7 @@ input[type=submit] {
display: inline-block; display: inline-block;
} }
.button:hover, .zeroclipboard-is-hover { .button:hover {
background: #E2E2E2; background: #E2E2E2;
} }
@@ -253,12 +254,62 @@ input[type=submit] {
font-weight: bold; font-weight: bold;
} }
.copy-button { .input-with-copy {
margin-top: 2px; position: relative;
} }
.copy-button:focus { .input-with-copy input:not([type=submit]):not([type=file]) {
outline: none; 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 { .social-button {

View File

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