ソースを参照

Initial commit

master
Said Achmiz 3年前
コミット
c42c3661d5
5個のファイルの変更367行の追加0行の削除
  1. 34
    0
      _htaccess
  2. 153
    0
      textfiles.css
  3. 93
    0
      textfiles.html
  4. 46
    0
      textfiles.js
  5. 41
    0
      textfiles.php

+ 34
- 0
_htaccess ファイルの表示

@@ -0,0 +1,34 @@
RewriteEngine on
RewriteBase /textfiles/

# Send requests without parameters to textfiles.php.
# RewriteRule ^$ textfiles.php [L]

# Send requests for index.php to textfiles.php.
# RewriteRule ^index\.php$ textfiles.php [L]

# Send requests for index.html to textfiles.php.
# RewriteRule ^index\.html$ textfiles.php [L]

# Send requests for textfiles.css to textfiles.css.
RewriteRule ^textfiles\.css$ textfiles.css [L]

# Send requests for textfiles.js to textfiles.js.
RewriteRule ^textfiles\.js$ textfiles.js [L]

# Send requests for textfiles.php to textfiles.php.
RewriteRule ^textfiles\.php$ textfiles.php [L]

# Send requests for textfiles.html to textfiles.php.
# NOTE: THIS IS NOT A TYPO!
RewriteRule ^textfiles\.html$ textfiles.php [L]

# Send requests for files that exist to textfiles.php (raw).
RewriteCond %{REQUEST_URI} ^\/textfiles\/(.+)/raw$
RewriteCond /file/path/to/your/textfiles/%1 -f
RewriteRule ^(.+)/raw$ textfiles.php?f=$1&m=raw [QSA,L]

# Send requests for files that exist to textfiles.php.
RewriteCond %{REQUEST_URI} ^\/textfiles\/(.+)$
RewriteCond /file/path/to/your/textfiles/%1 -f
RewriteRule ^(.+)$ textfiles.php?f=$1 [QSA,L]

+ 153
- 0
textfiles.css ファイルの表示

@@ -0,0 +1,153 @@
html {
box-sizing: border-box;
font-size: 20px;
}
*, *::before, *::after {
box-sizing: inherit;
}

html, body {
margin: 0;
padding: 0;
}

.compensator {
width: 15rem;
height: 4.5rem;
float: right;
pointer-events: none;
}
@media only screen and (max-width: 520px) {
.compensator {
display: none;
}
}

pre {
font-family: Inconsolata, monospace;
-moz-tab-size: 4;
tab-size: 4;
white-space: pre-wrap;
overflow-wrap: break-word;
padding: 0.5em;
}

#ui-elements-container {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100vh;
pointer-events: none;
}
#ui-elements-container > * {
pointer-events: auto;
}

#controls {
position: absolute;
top: 0;
right: 0;
-webkit-user-select: none;
-moz-user-select: none;
user-select: none;
}
@media only screen and (max-width: 520px) {
#controls {
display: flex;
flex-flow: row-reverse;
align-items: flex-end;
width: 100%;
top: unset;
bottom: 0;
}
}
#controls .buttons {
display: flex;
flex-flow: row-reverse wrap;
background-color: #fff;
padding: 1px;
}
@media only screen and (max-width: 520px) {
#controls .buttons {
flex-flow: column;
}
}

#controls .button {
background-color: #e00;
font-size: 1.5em;
display: flex;
flex-flow: column;
justify-content: center;
align-items: center;
width: 3.5rem;
height: 3.5rem;
text-decoration: none;
font-family: Font Awesome;
color: #fff;
padding: 1px 0 0 0;
border: none;
-webkit-appearance: none;
-moz-appearance: none;
cursor: pointer;
}
#controls .button + .button {
margin: 0 1px 0 0;
}
@media only screen and (max-width: 520px) {
#controls .button + .button {
margin: 1px 0 0 0;
}
}
@media only screen and (hover:hover) and (pointer:fine) {
#controls .button:hover {
color: gold;
}
}
#controls .button:active {
transform: scale(0.975);
}
#controls .button:focus {
outline: none;
}
#controls .button::after {
content: attr(data-label);
display: block;
font-family: sans-serif;
font-size: 0.5rem;
font-weight: bold;
margin: 6px 0 0 0;
text-transform: uppercase;
}

#controls .message {
display: block;
margin: 1px 0 0 0;
padding: 0.25em 0.5em;
text-align: center;
font-family: sans-serif;
font-size: 0.75em;
color: #b00;
}
#controls .message:not(:empty) {
background-color: #fff;
}
@media only screen and (max-width: 520px) {
#controls .message {
margin: 0 0 1px 1px;
flex: 1 1 100%;
padding: 0.5em 0.75em;
font-size: 0.875em;
}
#controls .message:not(:empty) {
outline: 1px solid #fff;
border: 1px solid #e00;
}
}

#scratchpad {
opacity: 0;
z-index: -1;
pointer-events: none;
}

+ 93
- 0
textfiles.html ファイルの表示

@@ -0,0 +1,93 @@
<?php

$filename = $_GET['f'];
$stylesheet = "textfiles.css";
$stylesheet_href = $stylesheet . "?v=" . filemtime($stylesheet);

?>

<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href='https://your.web.site/FontAwesome.css' type='text/css' rel='stylesheet' />
<link href='<?php echo $stylesheet_href; ?>' type='text/css' rel='stylesheet' />
<script type='text/javascript' src='textfiles.js'></script>
</head>
<body>

<div class='compensator'>
</div>

<pre>
<?php echo htmlentities(file_get_contents($filename)); ?>
</pre>

<div id='ui-elements-container'>
<div id='controls'>
<div class='buttons'>
<button
type='button'
class='button copy-raw-link'
title='Copy raw link to clipboard [k]'
data-label='Raw link'
data-main-action='copyRawLinkButtonClicked'
data-success-message='Raw file URL copied to clipboard.'
accesskey='k'
>&#xf121;</button>
<a
class='button raw'
title='View raw file [r]'
data-label='View raw'
accesskey='r'
href='<?php echo str_replace('.txt', '', $filename); ?>/raw'
>&#xf036;</a>
<button
type='button'
class='button copy-text'
title='Copy text to clipboard [c]'
data-label='Copy text'
data-main-action='copyTextButtonClicked'
data-success-message='Text copied to clipboard.'
accesskey='c'
>&#xf0c5;</button>
<button
type='button'
class='button copy-link'
title='Copy link to clipboard [l]'
data-label='Copy link'
data-main-action='copyLinkButtonClicked'
data-success-message='URL copied to clipboard.'
accesskey='l'
>&#xf0c1;</button>
</div>
<span class='message'></span>
</div>
<textarea id='scratchpad'></textarea>
</div>

</body>
<script type='text/javascript'>
copyLinkButtonClicked = () => {
copyTextToClipboard(location);
};
copyRawLinkButtonClicked = () => {
copyTextToClipboard(location + "/raw");
};
copyTextButtonClicked = () => {
selectElementContents(document.querySelector("pre"));
document.execCommand("copy");
};

document.querySelectorAll("#controls button").forEach(button => {
button.addActivateEvent((event) => {
event.target.blur();
window[event.target.dataset["mainAction"]]();
setMessage(event.target.dataset["successMessage"]);
});
});
setTimeout(() => {
selectElementContents(document.querySelector("pre"));
}, 0);
</script>
</html>

+ 46
- 0
textfiles.js ファイルの表示

@@ -0,0 +1,46 @@
/*******************************/
/* EVENT LISTENER MANIPULATION */
/*******************************/

/* Adds an event listener to a button (or other clickable element), attaching
it to both "click" and "keyup" events (for use with keyboard navigation).
Optionally also attaches the listener to the 'mousedown' event, making the
element activate on mouse down instead of mouse up. */
Element.prototype.addActivateEvent = function(func, includeMouseDown) {
let ael = this.activateEventListener = (event) => { if (event.button === 0 || event.key === ' ') func(event) };
if (includeMouseDown) this.addEventListener("mousedown", ael);
this.addEventListener("click", ael);
this.addEventListener("keyup", ael);
}

/* Removes event listener from a clickable element, automatically detaching it
from all relevant event types. */
Element.prototype.removeActivateEvent = function() {
let ael = this.activateEventListener;
this.removeEventListener("mousedown", ael);
this.removeEventListener("click", ael);
this.removeEventListener("keyup", ael);
}

/***********/
/* HELPERS */
/***********/

function selectElementContents(element) {
var range = document.createRange();
range.selectNodeContents(element);
var selection = window.getSelection();
selection.removeAllRanges();
selection.addRange(range);
}

function copyTextToClipboard(string) {
let scratchpad = document.querySelector("#scratchpad");
scratchpad.value = string;
scratchpad.select();
document.execCommand("copy");
}

function setMessage(string) {
document.querySelector("#controls .message").innerText = string;
}

+ 41
- 0
textfiles.php ファイルの表示

@@ -0,0 +1,41 @@
<?php

$base_url = "https://your.web.site/textfiles/";

if (isset($_GET['f'])) {
render_file();
} else if ( isset($_POST['f'])
&& isset($_POST['p'])
&& $_POST['p'] == 'YOUR_API_KEY_GOES_HERE') {
new_file();
} else {
header ('Content-type: text/plain; charset=utf-8');
http_response_code(404);
die("NO FILE FOR YOU!! COME BACK, ONE YEAR!");
}

## Functions

function render_file() {
if ($_GET['m'] == 'raw') {
header ('Content-type: text/plain; charset=utf-8');
echo file_get_contents($_GET['f']);
die;
} else {
header ('Content-type: text/html; charset=utf-8');
include_once(__DIR__ . "/textfiles.html");
die;
}
}

function new_file() {
`export LANG="en_US.UTF-8"`;
$tmp_file_path = trim(`mktemp -q ./XXXXXXXX`);
$tmp_file_name = `basename {$tmp_file_path}`;
`rm {$tmp_file_path}`;
file_put_contents("{$tmp_file_path}.txt", $_POST['f']);
global $base_url;
echo $base_url . $tmp_file_name;
}

?>

読み込み中…
キャンセル
保存