diff options
author | Aaron Parecki <aaron@parecki.com> | 2018-01-06 13:57:50 -0800 |
---|---|---|
committer | Aaron Parecki <aaron@parecki.com> | 2018-01-06 13:57:50 -0800 |
commit | 7047fe16da843d649baac375e9674f238072d7d5 (patch) | |
tree | 80e10520d5964d1bdd147d26317371d258abdf28 | |
parent | e5f88779f16c06f25ec4685bd07badfe5986d706 (diff) |
support posting code snippets
-rw-r--r-- | controllers/controllers.php | 102 | ||||
-rw-r--r-- | public/css/style.css | 5 | ||||
-rw-r--r-- | views/new-code.php | 116 | ||||
-rw-r--r-- | views/partials/code-bookmarklet.php | 3 |
4 files changed, 226 insertions, 0 deletions
diff --git a/controllers/controllers.php b/controllers/controllers.php index 8c371c7..bc13dd3 100644 --- a/controllers/controllers.php +++ b/controllers/controllers.php @@ -694,6 +694,108 @@ $app->post('/repost', function() use($app) { } }); +$app->get('/code', function() use($app) { + if($user=require_login($app)) { + $params = $app->request()->params(); + + $edit_data = ['content'=>'','name'=>'']; + + if(array_key_exists('edit', $params)) { + $source = get_micropub_source($user, $params['edit'], ['content','name']); + if(isset($source['content']) && is_array($source['content']) && isset($source['content'][0])) + $edit_data['content'] = $source['content'][0]; + if(isset($source['name']) && is_array($source['name']) && isset($source['name'][0])) + $edit_data['name'] = $source['name'][0]; + $url = $params['edit']; + } else { + $url = false; + } + + $languages = [ + 'php' => ['php'], + 'ruby' => ['rb'], + 'python' => ['py'], + 'perl' => ['pl'], + 'javascript' => ['js'], + 'html' => ['html','htm'], + 'css' => ['css'], + 'bash' => ['sh'], + 'nginx' => ['conf'], + 'apache' => [], + 'text' => ['txt'], + ]; + ksort($languages); + $language_map = []; + foreach($languages as $lang=>$exts) { + foreach($exts as $ext) + $language_map[$ext] = $lang; + } + + render('new-code', array( + 'title' => 'New Code Snippet', + 'url' => $url, + 'edit_data' => $edit_data, + 'token' => generate_login_token(), + 'languages' => $languages, + 'language_map' => $language_map, + 'my_hostname' => parse_url($user->url, PHP_URL_HOST), + 'authorizing' => false, + )); + } +}); + +$app->post('/code', function() use($app) { + if($user=require_login($app)) { + $params = $app->request()->params(); + + $error = false; + + if(isset($params['edit']) && $params['edit']) { + $micropub_request = [ + 'action' => 'update', + 'url' => $params['edit'], + 'replace' => [ + 'content' => [$params['content']] + ] + ]; + if(isset($params['name']) && $params['name']) { + $micropub_request['replace']['name'] = [$params['name']]; + } + $r = micropub_post_for_user($user, $micropub_request, null, true); + + if(isset($r['location']) && $r['location']) + $location = $r['location']; + elseif(in_array($r['code'], [200,201,204])) + $location = $params['edit']; + elseif(in_array($r['code'], [401,403])) { + $location = false; + $error = 'Your Micropub endpoint denied the request. Check that Quill is authorized to update posts.'; + } else { + $location = false; + $error = 'Your Micropub endpoint did not return a location header or a recognized response code'; + } + } else { + $micropub_request = array( + 'p3k-content-type' => 'code/' . $params['language'], + 'content' => $params['content'], + ); + if(isset($params['name']) && $params['name']) + $micropub_request['name'] = $params['name']; + + $r = micropub_post_for_user($user, $micropub_request); + + $location = $r['location']; + } + + $app->response()['Content-type'] = 'application/json'; + $app->response()->body(json_encode(array( + 'location' => $location, + 'error' => $r['error'], + 'error_details' => $error, + ))); + } +}); + $app->get('/reply/preview', function() use($app) { if($user=require_login($app)) { $params = $app->request()->params(); diff --git a/public/css/style.css b/public/css/style.css index 4a2acff..6dcf682 100644 --- a/public/css/style.css +++ b/public/css/style.css @@ -202,6 +202,11 @@ body { margin-top: 20px; } + textarea.code-snippet { + font-size: 12px; + font-family: "SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace; + } + /** * nicer file upload diff --git a/views/new-code.php b/views/new-code.php new file mode 100644 index 0000000..96a93d3 --- /dev/null +++ b/views/new-code.php @@ -0,0 +1,116 @@ + <div class="narrow"> + <?= partial('partials/header') ?> + + <div style="clear: both;" class="notice-pad"> + <div class="alert alert-success hidden" id="test_success"><strong>Success!</strong><br>Your post should be on your website now!<br><a href="" id="post_href">View your post</a></div> + <div class="alert alert-danger hidden" id="test_error"><strong>Your endpoint did not return a Location header.</strong><br>See <a href="/creating-a-micropub-endpoint">Creating a Micropub Endpoint</a> for more information.</div> + </div> + + <form role="form" style="margin-top: 20px;" id="note_form"> + + + <div class="form-group" id="note-name"> + <label for="note_name">File Name (optional)</label> + <input type="text" id="note_name" value="<?= htmlspecialchars($this->edit_data['name']) ?>" class="form-control" placeholder=""> + </div> + + <div class="form-group"> + <label for="note_content">Code</label> + <textarea id="note_content" value="" class="form-control code-snippet" style="height: 12em;"><?= htmlspecialchars($this->edit_data['content']) ?></textarea> + </div> + + <? if(!$this->url): ?> + <label for="note_language">Language</label> + <select class="form-control" id="note_language"> + <?php + foreach($this->languages as $lang=>$exts): + ?> + <option value="<?= $lang ?>"<?= $lang == 'text' ? ' selected="selected"' : '' ?>><?= $lang ?></option> + <?php + endforeach; + ?> + </select> + <? endif; ?> + + <div style="float: right; margin-top: 6px;"> + <button class="btn btn-success" id="btn_post"><?= $this->url ? 'Save' : 'Post' ?></button> + </div> + + <input type="hidden" id="edit_url" value="<?= $this->url ?>"> + </form> + + <div style="clear: both;"></div> + + <hr> + <div style="text-align: right;" id="bookmarklet"> + Bookmarklet: <a href="javascript:<?= js_bookmarklet('partials/code-bookmarklet', $this) ?>" class="btn btn-default btn-xs">code</a> + </div> + + </div> +<script> +$(function(){ + + var language_map = <?= json_encode($this->language_map) ?>; + + $("#note_name").on("keyup", function(){ + var name = $("#note_name").val(); + if(name && (m=name.match(/\.([a-z]+)$/))) { + if(language_map[m[1]]) { + $("#note_language").val(language_map[m[1]]); + } + } + }); + + $("#note_content").on('keyup', function(){ + var scrollHeight = document.getElementById("note_content").scrollHeight; + var currentHeight = parseInt($("#note_content").css("height")); + if(Math.abs(scrollHeight - currentHeight) > 20) { + $("#note_content").css("height", (scrollHeight+30)+"px"); + } + }); + + $("#btn_post").click(function(){ + $("#btn_post").addClass("loading disabled"); + + var syndications = []; + $("#syndication-container button.btn-info").each(function(i,btn){ + syndications.push($(btn).data('syndication')); + }); + + var params = { + content: $("#note_content").val(), + }; + if($("#edit_url").val() != "") { + params['edit'] = $("#edit_url").val(); + } else { + params['language'] = $("#note_language").val(); + } + if($("#note_name").val() != "") { + params['name'] = $("#note_name").val(); + } + + $.post("/code", params, function(response){ + if(response.location != false) { + + $("#test_success").removeClass('hidden'); + $("#test_error").addClass('hidden'); + $("#post_href").attr("href", response.location); + $("#note_form").addClass('hidden'); + + window.location = response.location; + } else { + $("#test_success").addClass('hidden'); + $("#test_error").removeClass('hidden'); + if(response.error_details) { + $("#test_error").text(response.error_details); + } + $("#btn_post").removeClass("loading disabled"); + } + + }); + return false; + }); + +}); + +</script> diff --git a/views/partials/code-bookmarklet.php b/views/partials/code-bookmarklet.php new file mode 100644 index 0000000..d0cf219 --- /dev/null +++ b/views/partials/code-bookmarklet.php @@ -0,0 +1,3 @@ +(function(){ + window.open("<?= Config::$base_url ?>code?"+(window.location.hostname=='<?= $this->my_hostname ?>'?"edit="+encodeURIComponent(window.location.href)+"&":"")+"token=<?= $this->token ?>"); +})(); |