mirror of
https://github.com/elder-plinius/P4RS3LT0NGV3.git
synced 2026-07-25 13:30:49 +02:00
Fix clipboard permission errors and add manual copy buttons
This commit is contained in:
+32
-33
@@ -210,33 +210,7 @@ button {
|
||||
transition: all 0.3s;
|
||||
}
|
||||
|
||||
.copy-button {
|
||||
position: absolute;
|
||||
top: 8px;
|
||||
right: 8px;
|
||||
padding: 6px;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background: var(--button-bg);
|
||||
border: 1px solid var(--input-border);
|
||||
border-radius: 4px;
|
||||
color: var(--text-color);
|
||||
cursor: pointer;
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
|
||||
.copy-button:hover {
|
||||
background: var(--button-hover-bg);
|
||||
border-color: var(--accent-color);
|
||||
color: var(--accent-color);
|
||||
}
|
||||
|
||||
.copy-button:active {
|
||||
transform: translateY(1px);
|
||||
}
|
||||
/* Copy button styling moved to a single definition below */
|
||||
|
||||
button:hover {
|
||||
background-color: var(--button-hover-bg);
|
||||
@@ -390,21 +364,46 @@ button:hover {
|
||||
position: absolute;
|
||||
top: 8px;
|
||||
right: 8px;
|
||||
padding: 8px;
|
||||
padding: 6px;
|
||||
background: var(--button-bg);
|
||||
border: none;
|
||||
border-radius: 6px;
|
||||
border: 1px solid var(--input-border);
|
||||
border-radius: 4px;
|
||||
color: var(--text-color);
|
||||
opacity: 0.7;
|
||||
opacity: 0.8;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s ease;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
.copy-button:hover {
|
||||
opacity: 1;
|
||||
background: var(--button-hover-bg);
|
||||
color: var(--main-bg-color);
|
||||
border-color: var(--accent-color);
|
||||
color: var(--accent-color);
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.copy-button:active {
|
||||
transform: translateY(1px);
|
||||
}
|
||||
|
||||
.decoded-message {
|
||||
position: relative;
|
||||
padding: 12px;
|
||||
background: var(--input-bg);
|
||||
border-radius: 4px;
|
||||
margin-top: 12px;
|
||||
border: 1px solid var(--input-border);
|
||||
font-family: 'Fira Code', monospace;
|
||||
word-break: break-word;
|
||||
}
|
||||
|
||||
/* Copy button hover styling is defined above */
|
||||
|
||||
.form-group label {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
+9
-3
@@ -101,7 +101,9 @@
|
||||
<div class="output-section" v-if="encodedMessage">
|
||||
<div class="output-container">
|
||||
<textarea readonly v-model="encodedMessage"></textarea>
|
||||
|
||||
<button class="copy-button" @click="copyToClipboard(encodedMessage)" title="Copy to clipboard">
|
||||
<i class="fas fa-copy"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -115,7 +117,9 @@
|
||||
></textarea>
|
||||
<div class="decoded-message" v-if="decodedMessage">
|
||||
{{ decodedMessage }}
|
||||
|
||||
<button class="copy-button" @click="copyToClipboard(decodedMessage.substring(decodedMessage.indexOf(': ') + 2))" title="Copy decoded text">
|
||||
<i class="fas fa-copy"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -161,7 +165,9 @@
|
||||
v-model="transformOutput"
|
||||
aria-label="Transformed text output"
|
||||
></textarea>
|
||||
|
||||
<button class="copy-button" @click="copyToClipboard(transformOutput)" title="Copy to clipboard">
|
||||
<i class="fas fa-copy"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -68,13 +68,13 @@ new Vue({
|
||||
|
||||
if (this.activeSteg === 'invisible') {
|
||||
this.encodedMessage = window.steganography.encodeInvisible(this.emojiMessage);
|
||||
this.copyToClipboard(this.encodedMessage);
|
||||
// Don't auto-copy to avoid clipboard permission errors
|
||||
} else if (this.selectedCarrier) {
|
||||
this.encodedMessage = window.steganography.encodeEmoji(
|
||||
this.selectedCarrier.emoji,
|
||||
this.emojiMessage
|
||||
);
|
||||
this.copyToClipboard(this.encodedMessage);
|
||||
// Don't auto-copy to avoid clipboard permission errors
|
||||
}
|
||||
},
|
||||
autoDecode() {
|
||||
@@ -88,7 +88,7 @@ new Vue({
|
||||
|
||||
if (result) {
|
||||
this.decodedMessage = `Decoded (${result.method}): ${result.text}`;
|
||||
this.copyToClipboard(result.text);
|
||||
// Don't auto-copy to avoid clipboard permission errors
|
||||
} else {
|
||||
this.decodedMessage = 'No encoded message detected';
|
||||
}
|
||||
@@ -101,35 +101,71 @@ new Vue({
|
||||
async copyToClipboard(text) {
|
||||
if (!text) return;
|
||||
|
||||
try {
|
||||
await navigator.clipboard.writeText(text);
|
||||
|
||||
// Show a brief notification
|
||||
const notification = document.createElement('div');
|
||||
notification.className = 'copy-notification';
|
||||
notification.innerHTML = '<i class="fas fa-check"></i> Copied!';
|
||||
document.body.appendChild(notification);
|
||||
|
||||
// Remove after animation
|
||||
setTimeout(() => {
|
||||
notification.classList.add('fade-out');
|
||||
setTimeout(() => document.body.removeChild(notification), 300);
|
||||
}, 1000);
|
||||
} catch (err) {
|
||||
console.error('Failed to copy text:', err);
|
||||
// Show error notification
|
||||
const notification = document.createElement('div');
|
||||
notification.className = 'copy-notification error';
|
||||
notification.innerHTML = '<i class="fas fa-times"></i> Copy failed';
|
||||
document.body.appendChild(notification);
|
||||
|
||||
setTimeout(() => {
|
||||
notification.classList.add('fade-out');
|
||||
setTimeout(() => document.body.removeChild(notification), 300);
|
||||
}, 1000);
|
||||
// Don't auto-copy in preview/iframe environments to avoid permission errors
|
||||
// Only copy when explicitly triggered by a button click
|
||||
const isExplicitUserAction = event && event.isTrusted;
|
||||
|
||||
// Only try to copy if we're not in a restricted environment or it's a direct user action
|
||||
if (isExplicitUserAction) {
|
||||
try {
|
||||
await navigator.clipboard.writeText(text);
|
||||
|
||||
// Show a success notification
|
||||
this.showNotification('<i class="fas fa-check"></i> Copied!', 'success');
|
||||
} catch (err) {
|
||||
console.warn('Clipboard access not available:', err);
|
||||
|
||||
// Try fallback method for copying (textarea method)
|
||||
this.fallbackCopy(text);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
fallbackCopy(text) {
|
||||
try {
|
||||
// Create temporary textarea
|
||||
const textarea = document.createElement('textarea');
|
||||
textarea.value = text;
|
||||
textarea.style.position = 'fixed'; // Avoid scrolling to bottom
|
||||
document.body.appendChild(textarea);
|
||||
textarea.select();
|
||||
|
||||
// Try the copy command
|
||||
const successful = document.execCommand('copy');
|
||||
|
||||
// Show appropriate notification
|
||||
if (successful) {
|
||||
this.showNotification('<i class="fas fa-check"></i> Copied!', 'success');
|
||||
} else {
|
||||
this.showNotification('<i class="fas fa-exclamation-triangle"></i> Copy not supported', 'error');
|
||||
}
|
||||
|
||||
// Clean up
|
||||
document.body.removeChild(textarea);
|
||||
} catch (err) {
|
||||
console.warn('Fallback copy method failed:', err);
|
||||
this.showNotification('<i class="fas fa-exclamation-triangle"></i> Copy not supported', 'error');
|
||||
}
|
||||
},
|
||||
|
||||
showNotification(message, type = 'success') {
|
||||
// Create notification element
|
||||
const notification = document.createElement('div');
|
||||
notification.className = `copy-notification ${type}`;
|
||||
notification.innerHTML = message;
|
||||
document.body.appendChild(notification);
|
||||
|
||||
// Remove after animation
|
||||
setTimeout(() => {
|
||||
notification.classList.add('fade-out');
|
||||
setTimeout(() => {
|
||||
if (notification.parentNode) {
|
||||
document.body.removeChild(notification);
|
||||
}
|
||||
}, 300);
|
||||
}, 1000);
|
||||
},
|
||||
|
||||
// Universal Decoder - tries all decoding methods
|
||||
universalDecode(input) {
|
||||
if (!input) return '';
|
||||
|
||||
Reference in New Issue
Block a user