Initial commit.

This is to be the new HashRU website based on the Aaronweb.net/Kabuki CMS.
This commit is contained in:
2016-09-01 23:13:23 +02:00
commit ab0e4efbcb
68 changed files with 8054 additions and 0 deletions

342
public/css/admin.css Normal file
View File

@@ -0,0 +1,342 @@
.admin_box {
margin: 0;
padding: 20px;
background: #fff;
box-shadow: 2px 2px 4px rgba(0, 0, 0, 0.3);
overflow: auto;
}
.admin_box h2 {
font: 700 24px "Open Sans", sans-serif;
margin: 0 0 0.2em;
}
.floatleft {
float: left;
}
.floatright {
float: right;
}
/* Admin bar styles
---------------------*/
body {
padding-top: 30px;
}
#admin_bar {
background: #333;
color: #ccc;
left: 0;
position: fixed;
top: 0;
width: 100%;
z-index: 100;
}
#admin_bar ul {
list-style: none;
margin: 0 auto;
max-width: 1280px;
min-width: 900px;
padding: 2px;
width: 95%;
}
#admin_bar ul > li {
display: inline;
border-right: 1px solid #aaa;
}
#admin_bar ul > li:last-child {
border-right: none;
}
#admin_bar li > a {
color: inherit;
display: inline-block;
padding: 4px 6px;
}
#admin_bar li a:hover {
text-decoration: underline;
}
/* Login box styles
---------------------*/
#login {
background: #fff;
border: 1px solid #aaa;
border-radius: 10px;
box-shadow: 2px 2px 4px rgba(0,0,0,0.1);
margin: 0 auto;
padding: 15px;
width: 275px;
}
#login * {
font-size: 15px;
line-height: 35px;
}
#login h3 {
font: 700 24px/36px "Open Sans", sans-serif;
margin: 0;
}
#login dd {
width: 96%;
margin: 0 0 10px;
}
#login input {
background: #eee;
border: 1px solid #aaa;
border-radius: 3px;
padding: 4px 5px;
width: 100%;
}
#login div {
text-align: right;
}
#login button {
line-height: 20px;
}
/* (Tag) autosuggest
----------------------*/
#new_tag_container {
display: block;
position: relative;
}
.autosuggest {
background: #fff;
border: 1px solid #ccc;
position: absolute;
top: 29px;
margin: 0;
padding: 0;
}
.autosuggest li {
display: block !important;
padding: 3px;
}
.autosuggest li:hover, .autosuggest li.selected {
background: #CFECF7;
cursor: pointer;
}
/* Edit user screen
---------------------*/
.edituser dt {
clear: left;
float: left;
width: 150px;
}
.edituser dd {
float: left;
margin-bottom: 5px;
}
.edituser form div:last-child {
padding: 1em 0 0;
}
/* Admin widgets
------------------*/
.widget {
background: #fff;
padding: 25px;
box-shadow: 2px 2px 4px rgba(0, 0, 0, 0.3);
}
.widget h3 {
margin: 0 0 1em;
font: 400 18px "Raleway", sans-serif;
}
.widget p, .errormsg p {
margin: 0;
}
.widget ul {
margin: 0;
list-style: none;
padding: 0;
}
.widget li {
line-height: 1.7em;
}
/* Edit icon on tiled grids
-----------------------------*/
.tiled_grid div.landscape, .tiled_grid div.portrait, .tiled_grid div.panorama {
position: relative;
}
.tiled_grid div > a.edit {
background: #fff;
border-radius: 3px;
box-shadow: 1px 1px 2px rgba(0,0,0,0.3);
display: none;
left: 20px;
line-height: 1.5;
padding: 5px 10px;
position: absolute;
top: 20px;
}
.tiled_grid div:hover > a.edit {
display: block;
}
/* Crop editor
----------------*/
#crop_editor {
position: fixed;
top: 0;
left: 0;
height: 100%;
width: 100%;
background: #000;
z-index: 100;
color: #fff;
}
#crop_editor input {
width: 50px;
background: #555;
color: #fff;
}
.crop_image_container {
position: relative;
}
.crop_position {
padding: 5px;
text-align: center;
}
.crop_position input, .crop_position .btn {
margin: 0 5px;
}
.crop_image_container img {
height: auto;
width: auto;
max-width: 100%;
max-height: 700px;
}
#crop_boundary {
border: 1px solid rgba(255, 255, 255, 0.75);
background: rgba(255, 255, 255, 0.75);
position: absolute;
z-index: 200;
width: 500px;
height: 300px;
top: 400px;
left: 300px;
filter: invert(100%); /* temp */
}
/* The pagination styles below are based on Bootstrap 2.3.2
-------------------------------------------------------------*/
.table_pagination, .table_form {
margin: 20px 0;
}
.table_pagination ul {
display: inline-block;
margin: 0;
padding: 0;
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
}
.table_pagination ul > li {
display: inline;
}
.table_pagination ul > li > a,
.table_pagination ul > li > span {
float: left;
padding: 4px 12px;
line-height: 20px;
text-decoration: none;
background-color: #ffffff;
border: 1px solid #dddddd;
border-left-width: 0;
}
.table_pagination ul > li > a:hover,
.table_pagination ul > li > a:focus,
.table_pagination ul > .active > a,
.table_pagination ul > .active > span {
background-color: #f5f5f5;
}
.table_pagination ul > .active > a,
.table_pagination ul > .active > span {
color: #999999;
cursor: default;
}
.table_pagination ul > .disabled > span,
.table_pagination ul > .disabled > a,
.table_pagination ul > .disabled > a:hover,
.table_pagination ul > .disabled > a:focus {
color: #999999;
cursor: default;
background-color: transparent;
}
.table_pagination ul > li:first-child > a,
.table_pagination ul > li:first-child > span {
border-left-width: 1px;
}
/* The table styles below were taken from Bootstrap 2.3.2
-----------------------------------------------------------*/
table {
max-width: 100%;
background-color: transparent;
border-collapse: collapse;
border-spacing: 0;
}
.table {
width: 100%;
margin-bottom: 20px;
}
.table th,
.table td {
border-top: 1px solid #dddddd;
line-height: 20px;
padding: 8px;
text-align: left;
vertical-align: top;
}
.table th {
font-weight: bold;
}
.table thead th {
vertical-align: bottom;
}
.table caption + thead tr:first-child th,
.table caption + thead tr:first-child td,
.table colgroup + thead tr:first-child th,
.table colgroup + thead tr:first-child td,
.table thead:first-child tr:first-child th,
.table thead:first-child tr:first-child td {
border-top: 0;
}
.table tbody + tbody {
border-top: 2px solid #dddddd;
}
.table .table {
background-color: #ffffff;
}
.table-striped tbody > tr:nth-child(odd) > td,
.table-striped tbody > tr:nth-child(odd) > th {
background-color: #f9f9f9;
}
.table-hover tbody tr:hover > td,
.table-hover tbody tr:hover > th {
background-color: #f5f5f5;
}

422
public/css/default.css Normal file
View File

@@ -0,0 +1,422 @@
/**
* Styles for the fifth version of Aaronweb.net.
* (C) Aaron van Geffen 2013, 2014
* DO NOT COPY OR RE-USE WITHOUT EXPLICIT WRITTEN PERMISSION. THANK YOU.
*/
@import url(//fonts.googleapis.com/css?family=Press+Start+2P);
@import url(//fonts.googleapis.com/css?family=Open+Sans:400,400italic,700,700italic);
body {
font: 13px/1.7 "Open Sans", "Helvetica", sans-serif;
padding: 0 0 3em;
margin: 0;
background: #99BFCE 0 -50% fixed;
background-image: radial-gradient(ellipse at top, #c3dee5 0%,#92b9ca 55%,#365e77 100%); /* W3C */
}
#wrapper, header {
width: 95%;
min-width: 900px;
max-width: 1280px;
margin: 0 auto;
}
header {
overflow: auto;
}
a {
color: #487C96;
text-decoration: none;
}
a:hover {
color: #222;
}
/* Logo
---------*/
h1#logo {
color: #fff;
float: left;
font: 200 50px 'Press Start 2P', "Helvetica Neue", sans-serif;
margin: 40px 0 50px 10px;
padding: 0;
text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.6);
}
h1#logo a {
text-decoration: none;
color: inherit;
}
h1#logo span.name {
padding-right: 7px;
}
h1#logo span.area:before {
content: '|';
font-weight: 400;
letter-spacing: 7px;
}
/* Navigation
---------------*/
ul#nav {
margin: 55px 10px 0 0;
padding: 0;
float: right;
list-style: none;
}
ul#nav li {
float: left;
}
ul#nav li a {
color: #fff;
display: block;
float: left;
font: 200 20px 'Press Start 2P', "Helvetica Neue", sans-serif;
margin: 0 0 0 32px;
padding: 10px 0;
text-decoration: none;
text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.7);
}
ul#nav li a:hover {
border-bottom: 3px solid rgba(255, 255, 255, 0.5);
}
/* Pagination
---------------*/
.pagination {
clear: both;
text-align: center;
}
.pagination ul {
display: inline-block;
margin: 0;
padding: 0;
box-shadow: 2px 2px 4px rgba(0, 0, 0, 0.3);
}
.pagination ul > li {
display: inline;
}
.pagination ul > li > a, .pagination ul > li > span {
float: left;
font: 300 18px/2.2 "Open Sans", "Helvetica", sans-serif;
padding: 6px 22px;
text-decoration: none;
background-color: #fff;
border-right: 1px solid #ddd;
}
.pagination ul > li > a:hover, .pagination ul > li > a:focus,
.pagination ul > .active > a, .pagination ul > .active > span {
background-color: #eee;
}
.pagination ul > .active > a, .pagination ul > .active > span {
cursor: default;
}
.pagination ul > .disabled > span, .pagination ul > .disabled > a,
.pagination ul > .disabled > a:hover, .pagination ul > .disabled > a:focus {
color: #999;
cursor: default;
background-color: transparent;
}
/* Tiled grid
---------------*/
.tiled_header, .page_title_box {
background: #fff;
box-shadow: 2px 2px 4px rgba(0, 0, 0, 0.3);
color: #000;
float: left;
margin: 0 0 1.5% 0;
font: 400 18px/2.2 "Open Sans", "Helvetica Neue", sans-serif;
padding: 6px 22px;
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
}
.page_title_box {
padding: 6px 22px !important;
clear: both;
display: inline-block;
float: none;
font: inherit;
}
.page_title_box h2 {
font: 400 18px/2.2 "Open Sans", "Helvetica Neue", sans-serif !important;
}
.page_title_box p {
margin: 0 0 10px;
}
.tiled_grid {
margin: 0;
padding: 0;
list-style: none;
}
.tiled_grid div.landscape, .tiled_grid div.portrait, .tiled_grid div.panorama,
.tiled_grid div.duo, .tiled_grid div.single {
background: #fff;
border-bottom-style: none !important;
box-shadow: 2px 2px 4px rgba(0, 0, 0, 0.3);
float: left;
line-height: 0;
margin: 0 3.5% 3.5% 0;
overflow: none;
position: relative;
padding-bottom: 5px;
width: 31%;
}
.tiled_grid div img {
border: none;
width: 100%;
}
.tiled_grid div h4 {
color: #000;
margin: 0;
font: 400 18px "Open Sans", "Helvetica Neue", sans-serif;
padding: 20px 5px 15px;
text-overflow: ellipsis;
text-align: center;
white-space: nowrap;
overflow: hidden;
}
.tiled_grid div a {
text-decoration: none;
}
.tiled_grid div.landscape:hover, .tiled_grid div.portrait:hover, .tiled_grid div.panorama:hover,
.tiled_grid div.duo:hover, .tiled_grid div.single:hover {
padding-bottom: 0;
border-bottom-width: 5px;
border-bottom-style: solid !important;
}
/* Panoramas */
.tiled_grid div.panorama, .tiled_grid .tiled_row {
clear: both;
float: left;
width: 100%;
margin-right: 0;
}
/* Tiling: one landscape, two tiles */
.tiled_row .column_landscape {
float: left;
width: 65.5%;
margin: 0 3.5% 3.5% 0;
}
.tiled_row .column_landscape div {
width: auto;
margin: 0;
}
.tiled_row .column_tiles_two {
float: left;
width: 31%;
}
.tiled_row .column_tiles_two div {
float: left;
width: 100%;
margin: 0 0 10% 0;
}
/* Tiling: big portrait, four tiles */
.tiled_row .column_portrait {
float: left;
width: 31%;
margin: 0 3.5% 3.5% 0;
}
.tiled_row .column_portrait div {
width: auto;
margin: 0;
}
.tiled_row .column_tiles_four {
float: left;
width: 65.5%;
}
.tiled_row .column_tiles_four div {
float: left;
width: 47.45%;
margin: 0 5% 5% 0;
}
/* Tiling: two tiles */
.tiled_row .duo {
width: 48.25% !important;
}
/* Tiling: one tile */
.tiled_row .single {
width: 48.25% !important;
}
/* Tiling: remove horizontal margin at end of row. */
.tiled_row > div:nth-child(3n),
.tiled_row > .duo:nth-child(2) {
margin-right: 0 !important;
}
.tiled_row .column_tiles_four > div:nth-child(2n) {
margin-right: 0;
}
/* Tiling: switch places for odd rows */
.tiled_row:nth-child(odd) .column_landscape,
.tiled_row:nth-child(odd) .column_portrait {
float: right;
margin: 0 0 3.5% 3.5%;
}
.tiled_row:nth-child(odd) .column_tiles_four {
float: right;
}
.tiled_row:nth-child(odd) .column_tiles_two {
float: right;
}
.boxed_content {
background: #fff;
padding: 25px;
box-shadow: 2px 2px 4px rgba(0, 0, 0, 0.3);
}
.boxed_content h2 {
font: 300 24px "Open Sans", "Helvetica Neue", sans-serif;
margin: 0 0 0.2em;
}
/* Error pages
----------------*/
.errormsg p {
font-size: 1.1em;
margin: 1em 0 0;
}
.errorpage .widget {
margin-top: 3%;
}
.errorpage .widget_recentposts {
margin-right: 0;
}
/* Footer
-----------*/
footer {
clear: both;
color: #fff;
font: 400 12px/1.7 "Open Sans", "Helvetica Neue", sans-serif;
padding: 40px 0 0;
text-align: center;
overflow: auto;
text-shadow: 1px 1px 1px rgba(0, 0, 0, 0.4);
}
footer a {
color: #eee;
}
/* Input
----------*/
input, select, .btn {
background: #fff;
border: 1px solid #ccc;
color: #000;
font: 13px/1.7 "Open Sans", "Helvetica", sans-serif;
padding: 3px;
}
input[type=submit], button, .btn {
background: #C5E2EA;
border-radius: 3px;
border: 1px solid #8BBFCE;
display: inline-block;
font: inherit;
padding: 4px 5px;
}
input[type=submit]:hover, button:hover, .btn:hover {
background-color: #bddce5;
border-color: #88b7c6;
}
textarea {
border: 1px solid #ccc;
font: 12px/1.4 'Monaco', 'Inconsolata', 'DejaVu Sans Mono', monospace;
padding: 0.75%;
width: 98.5%;
}
.btn-red {
background: #F3B076;
border-color: #C98245;
color: #000;
}
/* Responsive: smartphone in portrait
---------------------------------------*/
@media only screen and (max-width: 895px) {
#wrapper, header {
width: 100% !important;
min-width: 100% !important;
max-width: 100% !important;
}
h1#logo {
font-size: 42px;
float: none;
margin: 1em 0 0.5em;
text-align: center;
}
ul#nav {
float: none;
padding: 0;
margin: 2em 0 2.5em;
text-align: center;
overflow: none;
}
ul#nav li, ul#nav li a {
display: inline;
float: none;
}
ul#nav li a {
float: none;
font-size: 16px;
margin-left: 6px;
padding: 15px 4px;
}
.grid li {
margin: 0 0 5%;
width: 47.5%;
}
.grid li:nth-child(2n) {
margin-right: 0 !important;
}
.grid li:nth-child(2n+1) {
margin-right: 5% !important;
}
.tiled_header {
font-size: 14px;
margin: 0 0 3.5% 0;
}
.tiled_grid div h4 {
font-size: 14px;
padding: 15px 5px 10px;
}
.tiled_row > div, .tiled_row .single, .tiled_row .duo {
float: none !important;
width: 100% !important;
margin: 0 0 5% !important;
}
.tiled_row > div > div {
float: none !important;
width: 100% !important;
margin: 0 0 5% !important;
}
}

BIN
public/images/nothumb.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

10
public/index.php Normal file
View File

@@ -0,0 +1,10 @@
<?php
/*****************************************************************************
* index.php
* Bootstraps the framework.
*
* Kabuki CMS (C) 2013-2015, Aaron van Geffen
*****************************************************************************/
// Bootstrap the framework.
require_once dirname(__DIR__) . '/app.php';

38
public/js/ajax.js Normal file
View File

@@ -0,0 +1,38 @@
function HttpRequest(method, url, payload, callback, context) {
if (!window.XMLHttpRequest) {
return;
}
var request = new XMLHttpRequest();
var async = typeof callback !== 'undefined';
if (async) {
request.onreadystatechange = function() {
if (request.readyState !== 4) {
return;
}
if (request.responseText !== null && request.status === 200) {
var obj = JSON.parse(request.responseText);
if (obj.error) {
alert(obj.error);
return;
}
else {
callback(obj, context);
}
}
};
}
if (method === 'get') {
request.open('GET', url, async);
request.send(null);
} else {
request.open('POST', url, async);
request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
request.send(payload);
}
return request;
};

178
public/js/autosuggest.js Normal file
View File

@@ -0,0 +1,178 @@
/*
Copyright (c) 2015, Aaron van Geffen
All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted
provided that the following conditions are met:
- Redistributions of source code must retain the above copyright notice, this list of conditions
and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright notice, this list of conditions
and the following disclaimer in the documentation and/or other materials provided with the distribution.
*/
'use strict';
function AutoSuggest(opt) {
if (typeof opt.inputElement === "undefined" || typeof opt.listElement === "undefined" || typeof opt.baseUrl === "undefined" || typeof opt.appendCallback === "undefined") {
return;
}
this.input = document.getElementById(opt.inputElement);
this.input.autocomplete = "off";
this.list = document.getElementById(opt.listElement);
this.appendCallback = opt.appendCallback;
this.baseurl = opt.baseUrl;
var self = this;
this.input.addEventListener('keydown', function(event) {
self.doSelection(event);
}, false);
this.input.addEventListener('keyup', function(event) {
self.onType(this, event);
}, false);
}
AutoSuggest.prototype.doSelection = function(event) {
if (typeof this.container === "undefined" || this.container.children.length === 0) {
return;
}
switch (event.keyCode) {
case 13: // Enter
event.preventDefault();
this.container.children[this.selectedIndex].click();
break;
case 38: // Arrow up
case 40: // Arrow down
event.preventDefault();
this.findSelectedElement().className = '';
this.selectedIndex += event.keyCode === 38 ? -1 : 1;
if (this.selectedIndex < 0) {
this.selectedIndex = this.container.children.length - 1;
} else if (this.selectedIndex === this.container.children.length) {
this.selectedIndex = 0;
}
var new_el = this.findSelectedElement().className = 'selected';
break;
}
};
AutoSuggest.prototype.findSelectedElement = function() {
return this.container.children[this.selectedIndex];
};
AutoSuggest.prototype.onType = function(input, event) {
if (event.keyCode === 13 || event.keyCode === 38 || event.keyCode === 40) {
return;
}
var tokens = input.value.split(/\s+/).filter(function(token) {
return token.length >= 3;
});
if (tokens.length === 0) {
if (typeof this.container !== "undefined") {
this.clearContainer();
}
return false;
}
var request_uri = this.baseurl + '/suggest/?type=tags&data=' + window.encodeURIComponent(tokens.join(" "));
var request = new HttpRequest('get', request_uri, {}, this.onReceive, this);
};
AutoSuggest.prototype.onReceive = function(response, self) {
self.openContainer();
self.clearContainer();
self.fillContainer(response);
};
AutoSuggest.prototype.openContainer = function() {
if (this.container) {
if (!this.container.parentNode) {
this.input.parentNode.appendChild(this.container);
}
return this.container;
}
this.container = document.createElement('ul');
this.container.className = 'autosuggest';
this.input.parentNode.appendChild(this.container);
return this.container;
};
AutoSuggest.prototype.clearContainer = function() {
while (this.container.children.length > 0) {
this.container.removeChild(this.container.children[0]);
}
};
AutoSuggest.prototype.clearInput = function() {
this.input.value = "";
this.input.focus();
};
AutoSuggest.prototype.closeContainer = function() {
this.container.parentNode.removeChild(this.container);
};
AutoSuggest.prototype.fillContainer = function(response) {
var self = this;
this.selectedIndex = 0;
response.items.forEach(function(item, i) {
var node = document.createElement('li');
var text = document.createTextNode(item.label);
node.jsondata = item;
node.addEventListener('click', function(event) {
self.appendCallback(this.jsondata);
self.closeContainer();
self.clearInput();
});
node.appendChild(text);
self.container.appendChild(node);
if (self.container.children.length === 1) {
node.className = 'selected';
}
});
};
function TagAutoSuggest(opt) {
AutoSuggest.prototype.constructor.call(this, opt);
this.type = "tags";
}
TagAutoSuggest.prototype = Object.create(AutoSuggest.prototype);
TagAutoSuggest.prototype.constructor = TagAutoSuggest;
TagAutoSuggest.prototype.fillContainer = function(response) {
if (response.items.length > 0) {
AutoSuggest.prototype.fillContainer.call(this, response);
} else {
var node = document.createElement('li')
node.innerHTML = "<em>Tag does not exist yet. Create it?</em>";
var self = this;
node.addEventListener('click', function(event) {
self.createNewTag(function(response) {
console.log('Nieuwe tag!!');
console.log(response);
self.appendCallback(response);
});
self.closeContainer();
self.clearInput();
});
self.container.appendChild(node);
this.selectedIndex = 0;
node.className = 'selected';
}
};
TagAutoSuggest.prototype.createNewTag = function(callback) {
var request_uri = this.baseurl + '/managetags/?create';
var request = new HttpRequest('post', request_uri, 'tag=' + encodeURIComponent(this.input.value), callback, this);
}

218
public/js/crop_editor.js Normal file
View File

@@ -0,0 +1,218 @@
function CropEditor(opt) {
this.opt = opt;
this.edit_crop_button = document.createElement("span");
this.edit_crop_button.className = "btn";
this.edit_crop_button.innerHTML = "Edit crop";
this.edit_crop_button.addEventListener('click', this.show.bind(this));
this.thumbnail_select = document.getElementById(opt.thumbnail_select_id);
this.thumbnail_select.addEventListener('change', this.toggleCropButton.bind(this));
this.thumbnail_select.parentNode.insertBefore(this.edit_crop_button, this.thumbnail_select.nextSibling);
this.toggleCropButton();
}
CropEditor.prototype.buildContainer = function() {
this.container = document.createElement("div");
this.container.id = "crop_editor";
this.position = document.createElement("div");
this.position.className = "crop_position";
this.container.appendChild(this.position);
var source_x_label = document.createTextNode("Source X:");
this.position.appendChild(source_x_label);
this.source_x = document.createElement("input");
this.source_x.addEventListener("keyup", this.positionBoundary.bind(this));
this.position.appendChild(this.source_x);
var source_y_label = document.createTextNode("Source Y:");
this.position.appendChild(source_y_label);
this.source_y = document.createElement("input");
this.source_y.addEventListener("keyup", this.positionBoundary.bind(this));
this.position.appendChild(this.source_y);
var crop_width_label = document.createTextNode("Crop width:");
this.position.appendChild(crop_width_label);
this.crop_width = document.createElement("input");
this.crop_width.addEventListener("keyup", this.positionBoundary.bind(this));
this.position.appendChild(this.crop_width);
var crop_height_label = document.createTextNode("Crop height:");
this.position.appendChild(crop_height_label);
this.crop_height = document.createElement("input");
this.crop_height.addEventListener("keyup", this.positionBoundary.bind(this));
this.position.appendChild(this.crop_height);
this.save_button = document.createElement("span");
this.save_button.className = "btn";
this.save_button.innerHTML = "Save";
this.save_button.addEventListener('click', this.save.bind(this));
this.position.appendChild(this.save_button);
this.abort_button = document.createElement("span");
this.abort_button.className = "btn btn-red";
this.abort_button.innerHTML = "Abort";
this.abort_button.addEventListener('click', this.hide.bind(this));
this.position.appendChild(this.abort_button);
this.image_container = document.createElement("div");
this.image_container.className = "crop_image_container";
this.container.appendChild(this.image_container);
this.crop_boundary = document.createElement("div");
this.crop_boundary.id = "crop_boundary";
this.image_container.appendChild(this.crop_boundary);
this.original_image = document.createElement("img");
this.original_image.id = "original_image";
this.original_image.src = this.opt.original_image_src;
this.image_container.appendChild(this.original_image);
this.parent = document.getElementById(this.opt.editor_container_parent_id);
this.parent.appendChild(this.container);
};
CropEditor.prototype.setInputValues = function() {
var current = this.thumbnail_select.options[this.thumbnail_select.selectedIndex].dataset;
if (typeof current.crop_region === "undefined") {
var source_ratio = this.original_image.naturalWidth / this.original_image.naturalHeight,
crop_ratio = current.crop_width / current.crop_height,
min_dim = Math.min(this.original_image.naturalWidth, this.original_image.naturalHeight);
// Cropping from the centre?
if (current.crop_method === "c") {
// Crop vertically from the centre, using the entire width.
if (source_ratio < crop_ratio) {
this.crop_width.value = this.original_image.naturalWidth;
this.crop_height.value = Math.ceil(this.original_image.naturalWidth / crop_ratio);
this.source_x.value = 0;
this.source_y.value = Math.ceil((this.original_image.naturalHeight - this.crop_height.value) / 2);
}
// Crop horizontally from the centre, using the entire height.
else {
this.crop_width.value = Math.ceil(current.crop_width * this.original_image.naturalHeight / current.crop_height);
this.crop_height.value = this.original_image.naturalHeight;
this.source_x.value = Math.ceil((this.original_image.naturalWidth - this.crop_width.value) / 2);
this.source_y.value = 0;
}
}
// Cropping a top or bottom slice?
else {
// Can we actually take a top or bottom slice from the original image?
if (source_ratio < crop_ratio) {
this.crop_width.value = this.original_image.naturalWidth;
this.crop_height.value = Math.floor(this.original_image.naturalHeight / crop_ratio);
this.source_x.value = "0";
this.source_y.value = current.crop_method.indexOf("t") !== -1 ? "0" : this.original_image.naturalHeight - this.crop_height.value;
}
// Otherwise, take a vertical slice from the centre.
else {
this.crop_width.value = Math.floor(this.original_image.naturalHeight * crop_ratio);
this.crop_height.value = this.original_image.naturalHeight;
this.source_x.value = Math.floor((this.original_image.naturalWidth - this.crop_width.value) / 2);
this.source_y.value = "0";
}
}
} else {
var region = current.crop_region.split(',');
this.crop_width.value = region[0];
this.crop_height.value = region[1];
this.source_x.value = region[2];
this.source_y.value = region[3];
}
};
CropEditor.prototype.showContainer = function() {
this.container.style.display = "block";
this.setInputValues();
this.positionBoundary();
}
CropEditor.prototype.save = function() {
var current = this.thumbnail_select.options[this.thumbnail_select.selectedIndex].dataset;
var payload = {
thumb_width: current.crop_width,
thumb_height: current.crop_height,
crop_method: current.crop_method,
crop_width: this.crop_width.value,
crop_height: this.crop_height.value,
source_x: this.source_x.value,
source_y: this.source_y.value
};
var req = HttpRequest("post", this.parent.action + "?id=" + this.opt.asset_id + "&updatethumb",
"data=" + encodeURIComponent(JSON.stringify(payload)), function(response) {
this.opt.after_save(response);
this.hide();
}.bind(this));
};
CropEditor.prototype.show = function() {
if (typeof this.container === "undefined") {
this.buildContainer();
}
// Defer showing and positioning until image is loaded.
// !!! TODO: add a spinner in the mean time?
if (this.original_image.naturalWidth > 0) {
this.showContainer();
} else {
this.original_image.addEventListener("load", function() {
this.showContainer();
}.bind(this));
}
};
CropEditor.prototype.hide = function() {
this.container.style.display = "none";
};
CropEditor.prototype.addEvents = function(event) {
var drag_target = document.getElementById(opt.drag_target);
drag_target.addEventListener('dragstart', this.dragStart);
drag_target.addEventListener('drag', this.drag);
drag_target.addEventListener('dragend', this.dragEnd);
};
CropEditor.prototype.dragStart = function(event) {
console.log(event);
event.preventDefault();
};
CropEditor.prototype.dragEnd = function(event) {
console.log(event);
};
CropEditor.prototype.drag = function(event) {
console.log(event);
};
CropEditor.prototype.toggleCropButton = function() {
var current = this.thumbnail_select.options[this.thumbnail_select.selectedIndex].dataset;
this.edit_crop_button.style.display = typeof current.crop_method === "undefined" ? "none" : "";
};
CropEditor.prototype.positionBoundary = function(event) {
var source_x = parseInt(this.source_x.value),
source_y = parseInt(this.source_y.value),
crop_width = parseInt(this.crop_width.value),
crop_height = parseInt(this.crop_height.value),
real_width = this.original_image.naturalWidth,
real_height = this.original_image.naturalHeight,
scaled_width = this.original_image.clientWidth,
scaled_height = this.original_image.clientHeight;
var width_scale = scaled_width / real_width,
height_scale = scaled_height / real_height;
crop_boundary.style.left = (this.source_x.value) * width_scale + "px";
crop_boundary.style.top = (this.source_y.value) * height_scale + "px";
crop_boundary.style.width = (this.crop_width.value) * width_scale + "px";
crop_boundary.style.height = (this.crop_height.value) * height_scale + "px";
};

3
public/robots.txt Normal file
View File

@@ -0,0 +1,3 @@
User-agent: *
Disallow: /login