-
Notifications
You must be signed in to change notification settings - Fork 275
Expand file tree
/
Copy pathexperiment.html
More file actions
227 lines (185 loc) · 7.79 KB
/
experiment.html
File metadata and controls
227 lines (185 loc) · 7.79 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
<!DOCTYPE html>
<html>
<head>
<title>Clipboard Performance Test</title>
<link rel="stylesheet" href="./experiment_styles.css">
</head>
<body>
<h1>Clipboard Performance Test</h1>
<div class="controls">
<div class="how-to-use">
<h3>How to use</h3>
<ol>
<li>Write only text to clipboard by clicking on "Write 1MB Text Only" button.</li>
<li>Read from clipboard by clicking on "Read from Clipboard" button.</li>
<li>Write text and HTML to clipboard by clicking on "Write 1MB Text + 3MB HTML" button.</li>
<li>Read from clipboard by clicking on "Read from Clipboard" button.</li>
<li>Read selected format from clipboard by clicking on "Selected Format Read from Clipboard" button.</li>
</ol>
<div class="note">
<strong>Note:</strong> Do not consider the results when clipboard read permission is asked for the first time.
</div>
</div>
<h3>Write Data to Clipboard</h3>
<button id="write-text-btn">Write 1MB Text Only</button>
<button id="write-text-html-btn">Write 1MB Text + 3MB HTML</button>
<h3>Read Data from Clipboard</h3>
<button id="read-btn">Read from Clipboard</button>
<h4>Selected Format Read</h4>
<div class="format-selection">
<label>Select formats to read:</label><br>
<input type="checkbox" id="text-plain-checkbox" value="text/plain">
<label for="text-plain-checkbox">text/plain</label><br>
<input type="checkbox" id="text-html-checkbox" value="text/html">
<label for="text-html-checkbox">text/html</label><br>
<input type="checkbox" id="image-png-checkbox" value="image/png">
<label for="image-png-checkbox">image/png</label><br>
</div>
<button id="selected-format-read-btn">Selected Format Read from Clipboard</button>
<button id="clear-results-btn">Clear Results</button>
</div>
<table class="results-table" id="results-table">
<thead>
<tr>
<th>#</th>
<th>Time</th>
<th>Clipboard Read Type</th>
<th>Read Time (ms)</th>
</tr>
</thead>
<tbody id="results-body">
<!-- Results will be added here -->
</tbody>
</table>
<div class="log" id="log"></div>
<script>
function log(message, type = 'info') {
const logElement = document.getElementById('log');
const timestamp = new Date().toLocaleTimeString();
const entry = document.createElement('div');
entry.className = type;
entry.innerHTML = `[${timestamp}] ${message}`;
logElement.appendChild(entry);
logElement.scrollTop = logElement.scrollHeight;
}
// Generates data of specified size in MB
function generateDataOfSize(sizeInMB) {
const bytesPerMB = 1024 * 1024;
const targetBytes = sizeInMB * bytesPerMB;
log(`Generating ${sizeInMB} MB of data...`);
// Each character in JavaScript is 2 bytes (UTF-16)
const totalChars = targetBytes / 2;
const result = 'A'.repeat(totalChars);
log(`Data generated: ${(result.length * 2 / bytesPerMB).toFixed(2)} MB`, "success");
return result;
}
// Writes text-only data to clipboard
async function writeTextOnly() {
try {
log("Writing 1MB text data to clipboard...");
const textData = generateDataOfSize(1);
const clipboardItems = {
'text/plain': new Blob([textData], { type: 'text/plain' })
};
await navigator.clipboard.write([new ClipboardItem(clipboardItems)]);
log("Text data written successfully", "success");
} catch (error) {
log(`Error writing text data: ${error.message}`, "error");
}
}
// Writes text and HTML data to clipboard
async function writeTextAndHTMLData() {
try {
log("Writing 1MB text + 3MB HTML data to clipboard...");
const textData = generateDataOfSize(1);
const htmlData = `<html><body><pre>${generateDataOfSize(3)}</pre></body></html>`;
const clipboardItems = {
'text/plain': new Blob([textData], { type: 'text/plain' }),
'text/html': new Blob([htmlData], { type: 'text/html' })
};
await navigator.clipboard.write([new ClipboardItem(clipboardItems)]);
log("Text & HTML data written successfully", "success");
} catch (error) {
log(`Error writing Text & HTML data: ${error.message}`, "error");
}
}
// Reads text from clipboard and measure time
async function readTextFromClipboard() {
const startTime = performance.now();
try {
log("Reading data from clipboard...");
const clipboardData = await navigator.clipboard.read();
const endTime = performance.now();
const readTime = endTime - startTime;
log(`Read completed in ${readTime.toFixed(2)} ms`, "success");
log(`Available item types: [${clipboardData[0].types.join(', ')}]`, "info");
// Add result to table
addResult(`read()`, readTime);
} catch (error) {
log(`Error reading from clipboard: ${error.message}`, "error");
}
}
// Reads selected format from clipboard
async function readSelectedFormatFromClipboard() {
const checkboxes = document.querySelectorAll('.format-selection input[type="checkbox"]:checked');
const selectedTypes = Array.from(checkboxes).map(cb => cb.value);
const startTime = performance.now();
try {
if (selectedTypes.length === 0) {
log("No formats selected. Reading all formats...");
} else {
log(`Reading selected formats from clipboard: [${selectedTypes.join(', ')}] ...`);
}
const clipboardData = await navigator.clipboard.read({ types: selectedTypes });
const endTime = performance.now();
const readTime = endTime - startTime;
log(`Selected formats read completed in ${readTime.toFixed(2)} ms for [${selectedTypes.join(', ')}]`, "success");
const item = clipboardData[0];
log(`Available item types: [${item.types.join(', ')}]`, "info");
for (const type of selectedTypes) {
item.getType(type).then(blob => {
log(`getType(${type}) success`, "success");
}).catch(err => {
log(`getType(${type}) failed: ${err.message}`, "error");
});
}
addResult(`read( { types: [ ${selectedTypes.join(', ')} ] } )`, readTime);
} catch (error) {
log(`Error reading selected format from clipboard: ${error.message}`, "error");
}
}
let resultNumber = 1;
// Adds result to the table
function addResult(readType, readTime) {
const tableBody = document.getElementById('results-body');
const row = document.createElement('tr');
const timestamp = new Date().toLocaleTimeString();
row.innerHTML = `
<td>${resultNumber++}</td>
<td>${timestamp}</td>
<td>${readType}</td>
<td>${readTime.toFixed(2)}</td>
`;
tableBody.appendChild(row);
}
function clearResults() {
document.getElementById('results-body').innerHTML = '';
resultNumber = 1;
log("Results table cleared", "info");
}
document.getElementById('write-text-btn')
.addEventListener('click', writeTextOnly);
document.getElementById('write-text-html-btn')
.addEventListener('click', writeTextAndHTMLData);
document.getElementById('read-btn')
.addEventListener('click', readTextFromClipboard);
document.getElementById('selected-format-read-btn')
.addEventListener('click', readSelectedFormatFromClipboard);
document.getElementById('clear-results-btn')
.addEventListener('click', clearResults);
// Initialize
log("Click 'Write 1MB Text Only' or 'Write 1MB Text + 3MB HTML' to start testing");
log("Or click 'Read from Clipboard' to test reading existing clipboard data");
</script>
</body>
</html>