Browse Source

Merge

Signed-off-by: Tamas Kocsis <hello@zeronet.io>
shortcutme 7 years ago
parent
commit
19d21cb1b2
4 changed files with 157 additions and 11 deletions
  1. 1 1
      alloy-editor/all.css
  2. 8 2
      alloy-editor/all.js
  3. 2 2
      css/all.css
  4. 146 6
      js/all.js

+ 1 - 1
alloy-editor/all.css

@@ -719,4 +719,4 @@ For licensing, see LICENSE.md or http://ckeditor.com/license
 h2.empty:before { content: "Heading"; color: #DDD; position: absolute; pointer-events: none; }
 h3.empty:before { content: "Sub-Heading"; color: #DDD; position: absolute; pointer-events: none; }
 
-.meditor hr { display: block !important }
+.meditor hr:first-of-type { display: block !important; position: absolute; margin: 0px; border-bottom: 1px dashed #DEDEDE; width: 100% }

+ 8 - 2
alloy-editor/all.js

@@ -975,6 +975,12 @@ selections.unshift({
     buttons: ['bold', 'italic', 'strike', 'inlinecode', 'link'],
     test: AlloyEditor.SelectionTest.text
 })
+// Remove Image toolbar
+AlloyEditor.Core.ATTRS.toolbars.value.styles.selections.forEach(
+    function(selection, i, selections) {
+        if (selection.name == "image") selections.splice(i, 1)
+    }
+)
 
 
 // Other settings
@@ -983,7 +989,7 @@ CKEDITOR.config.title = ""
 CKEDITOR.config.fullPage  = true
 CKEDITOR.config.pasteFromWordRemoveFontStyles = true
 CKEDITOR.config.removePlugins = "dragdrop"
-AlloyEditor.Core.ATTRS.removePlugins.value += ',ae_embed'
+AlloyEditor.Core.ATTRS.removePlugins.value += ',ae_embed,ae_imagealignment,ae_dragresize'
 AlloyEditor.Buttons.linkEdit.defaultProps.appendProtocol = false
 CKEDITOR.config.buttonCfg = {
     buttonLinkEdit: {
@@ -992,7 +998,7 @@ CKEDITOR.config.buttonCfg = {
 }
 AlloyEditor.Core.ATTRS.toolbars.value = {
     add: {
-        buttons: ['h2', 'h3', 'quote', 'code', 'hline', 'table'],
+        buttons: ['h2', 'h3', 'quote', 'code', 'hline', 'table', 'image'],
         tabIndex: 2
     },
     styles: {

+ 2 - 2
css/all.css

@@ -176,7 +176,7 @@ a:hover { color: #3498db }
 
 .bottombar {
 	display: none; position: fixed; padding: 10px 20px; opacity: 0; background-color: rgba(255,255,255,0.9);
-	right: 30px; bottom: 0px; z-index: 999; -webkit-transition: all 0.3s; -moz-transition: all 0.3s; -o-transition: all 0.3s; -ms-transition: all 0.3s; transition: all 0.3s ; transform: translateY(50px)
+	right: 30px; bottom: 0px; z-index: 1000; -webkit-transition: all 0.3s; -moz-transition: all 0.3s; -o-transition: all 0.3s; -ms-transition: all 0.3s; transition: all 0.3s ; transform: translateY(50px)
 }
 .bottombar.visible { -webkit-transform: translateY(0px); -moz-transform: translateY(0px); -o-transform: translateY(0px); -ms-transform: translateY(0px); transform: translateY(0px) ; opacity: 1 }
 .publishbar { z-index: 990}
@@ -260,7 +260,7 @@ code {
 	color: #444; font-weight: normal; font-size: 13px; vertical-align: text-bottom; border-bottom-width: 2px;
 }
 .post .body pre { table-layout: fixed; width: auto; display: table; white-space: normal; }
-.post .body pre code { padding: 10px 20px; white-space: pre; max-width: 850px }
+.post .body pre code { padding: 10px 20px; white-space: pre; max-width: 850px; display: block }
 
 blockquote { border-left: 3px solid #333; margin-left: 0px; padding-left: 1em }
 /*.post .more {

+ 146 - 6
js/all.js

@@ -612,6 +612,9 @@
       this.handleChange = __bind(this.handleChange, this);
       this.handleCommand = __bind(this.handleCommand, this);
       this.handleAction = __bind(this.handleAction, this);
+      this.handleImageAdd = __bind(this.handleImageAdd, this);
+      this.getExtension = __bind(this.getExtension, this);
+      this.resizeImage = __bind(this.resizeImage, this);
       editor = AlloyEditor.editable(this.tag);
       el = editor._editor.element.$;
       height_before = el.getClientRects()[0].height;
@@ -630,16 +633,109 @@
       })(this));
       editor.get('nativeEditor').on("click", this.handleSelectionChange);
       editor.get('nativeEditor').on("change", this.handleChange);
-      editor.get('nativeEditor').on('imageAdd', function(e) {
-        return e.data.el.remove();
-      });
+      editor.get('nativeEditor').on('imageAdd', this.handleImageAdd);
       editor.get('nativeEditor').on("actionPerformed", this.handleAction);
       editor.get('nativeEditor').on('afterCommandExec', this.handleCommand);
       window.editor = editor;
       this.el_last_created = null;
-      return editor;
+      this.image_size_limit = 200 * 1024;
+      this.image_resize_width = 1200;
+      this.image_resize_height = 900;
+      this.image_preverse_ratio = true;
+      this.image_try_png = false;
+      return this;
     }
 
+    CustomAlloyEditor.prototype.calcSize = function(source_width, source_height, target_width, target_height) {
+      var height, width;
+      if (source_width <= target_width && source_height <= target_height) {
+        return [source_width, source_height];
+      }
+      width = target_width;
+      height = width * (source_height / source_width);
+      if (height > target_height) {
+        height = target_height;
+        width = height * (source_width / source_height);
+      }
+      return [Math.round(width), Math.round(height)];
+    };
+
+    CustomAlloyEditor.prototype.scaleHalf = function(image) {
+      var canvas, ctx;
+      canvas = document.createElement("canvas");
+      canvas.width = image.width / 1.5;
+      canvas.height = image.height / 1.5;
+      ctx = canvas.getContext("2d");
+      ctx.drawImage(image, 0, 0, canvas.width, canvas.height);
+      return canvas;
+    };
+
+    CustomAlloyEditor.prototype.resizeImage = function(image, width, height) {
+      var canvas, ctx, image_base64uri, image_resized, _ref;
+      canvas = document.createElement("canvas");
+      if (this.image_preverse_ratio) {
+        _ref = this.calcSize(image.width, image.height, width, height), canvas.width = _ref[0], canvas.height = _ref[1];
+      } else {
+        canvas.width = width;
+        canvas.height = height;
+      }
+      ctx = canvas.getContext("2d");
+      ctx.fillStyle = "#FFF";
+      ctx.fillRect(0, 0, canvas.width, canvas.height);
+      image_resized = image;
+      while (image_resized.width > width * 1.5) {
+        image_resized = this.scaleHalf(image_resized);
+      }
+      ctx.drawImage(image_resized, 0, 0, canvas.width, canvas.height);
+      if (this.image_try_png && this.getExtension(image.src) === "png") {
+
+        /*
+        			quant = new RgbQuant({colors: 256, method: 1})
+        			quant.sample(canvas)
+        			quant.palette(true)
+        			canvas_quant = drawPixels(quant.reduce(canvas), width)
+        			optimizer = new CanvasTool.PngEncoder(canvas_quant, { bitDepth: 8, colourType: CanvasTool.PngEncoder.ColourType.TRUECOLOR })
+        			image_base64uri = "data:image/png;base64," + btoa(optimizer.convert())
+         */
+        image_base64uri = canvas.toDataURL("image/png", 0.1);
+        if (image_base64uri.length > this.image_size_limit) {
+          this.log("PNG too large (" + image_base64uri.length + " bytes), convert to jpg instead");
+          image_base64uri = canvas.toDataURL("image/jpeg", 0.7);
+        } else {
+          this.log("Converted to PNG");
+        }
+      } else {
+        image_base64uri = canvas.toDataURL("image/jpeg", 0.7);
+      }
+      this.log("Resized " + image.width + "x" + image.height + " to " + canvas.width + "x" + canvas.height + " (" + image_base64uri.length + " bytes)");
+      return [image_base64uri, canvas.width, canvas.height];
+    };
+
+    CustomAlloyEditor.prototype.getExtension = function(data) {
+      return data.match("/[a-z]+")[0].replace("/", "").replace("jpeg", "jpg");
+    };
+
+    CustomAlloyEditor.prototype.handleImageAdd = function(e) {
+      var height, image_base64uri, name, width, _ref;
+      if (e.data.file.name) {
+        name = e.data.file.name.replace(/[^\w\.-]/gi, "_");
+      } else {
+        name = Time.timestamp() + "." + this.getExtension(e.data.file.type);
+      }
+      e.data.el.$.style.maxWidth = "2400px";
+      if (e.data.file.size > this.image_size_limit) {
+        this.log("File size " + e.data.file.size + " larger than allowed " + this.image_size_limit + ", resizing...");
+        _ref = this.resizeImage(e.data.el.$, this.image_resize_width, this.image_resize_height), image_base64uri = _ref[0], width = _ref[1], height = _ref[2];
+        e.data.el.$.src = image_base64uri;
+        name = name.replace(/(png|gif|jpg)/, this.getExtension(image_base64uri));
+      } else {
+        image_base64uri = e.data.el.$.src;
+      }
+      e.data.el.$.style.maxWidth = "";
+      e.data.el.$.alt = name + " (" + width + "x" + height + ")";
+      return this.handleImageSave(name, image_base64uri, e.data.el.$);
+    };
+
     CustomAlloyEditor.prototype.handleAction = function(e) {
       var el, new_el, ranges;
       el = e.editor.getSelection().getStartElement();
@@ -749,7 +845,6 @@
 }).call(this);
 
 
-
 /* ---- /1BLogC9LN4oPDcruNz3qo1ysa133E9AGg8/js/utils/Follow.coffee ---- */
 
 
@@ -927,6 +1022,7 @@
       this.deleteObject = __bind(this.deleteObject, this);
       this.saveEdit = __bind(this.saveEdit, this);
       this.stopEdit = __bind(this.stopEdit, this);
+      this.handleImageSave = __bind(this.handleImageSave, this);
       this.startEdit = __bind(this.startEdit, this);
       this.edit_button = $("<a href='#Edit' class='editable-edit icon-edit'></a>");
       this.edit_button.on("click", this.startEdit);
@@ -960,6 +1056,7 @@
       this.content_before = this.elem.html();
       if (this.elem.data("editable-mode") === "meditor") {
         this.editor = new Meditor(this.elem[0], this.getContent(this.elem, "raw"));
+        this.editor.handleImageSave = this.handleImageSave;
         this.editor.load();
       } else {
         this.editor = $("<textarea class='editor'></textarea>");
@@ -999,6 +1096,19 @@
       return false;
     };
 
+    InlineEditor.prototype.handleImageSave = function(name, image_base64uri, el) {
+      var file_path, object_name;
+      el.style.opacity = 0.5;
+      object_name = this.getObject(this.elem).data("object").replace(/[^A-Za-z0-9]/g, "_").toLowerCase();
+      file_path = "data/img/" + object_name + "_" + name;
+      return Page.cmd("fileWrite", [file_path, image_base64uri.replace(/.*,/, "")], (function(_this) {
+        return function() {
+          el.style.opacity = 1;
+          return el.src = file_path;
+        };
+      })(this));
+    };
+
     InlineEditor.prototype.stopEdit = function() {
       this.editor.remove();
       this.editor = null;
@@ -1053,6 +1163,7 @@
       $('pre code').each(function(i, block) {
         return hljs.highlightBlock(block);
       });
+      Page.cleanupImages();
       return false;
     };
 
@@ -1113,6 +1224,7 @@
 }).call(this);
 
 
+
 /* ---- /1BLogC9LN4oPDcruNz3qo1ysa133E9AGg8/js/utils/Meditor.coffee ---- */
 
 
@@ -1169,6 +1281,9 @@
       this.tag_editmode = this.tag.previousSibling;
       this.tag_editmode.onclick = this.handleEditmodeChange;
       this.editor = new CustomAlloyEditor(this.tag);
+      if (this.handleImageSave) {
+        this.editor.handleImageSave = this.handleImageSave;
+      }
       this.tag.insertAdjacentHTML('beforeBegin', this.tag_original.outerHTML);
       this.tag_markdown = this.tag.previousSibling;
       this.tag_markdown.innerHTML = "<textarea class='meditor-markdown'>MARKDOWN</textarea>";
@@ -2383,6 +2498,7 @@
           return _this.writeData(data, function(res) {
             if (cb) {
               if (res === true) {
+                _this.cleanupImages();
                 if (elem.data("editable-mode") === "simple") {
                   return cb(content);
                 } else if (elem.data("editable-mode") === "timestamp") {
@@ -2637,6 +2753,30 @@
       return false;
     };
 
+    ZeroBlog.prototype.cleanupImages = function() {
+      return this.cmd("fileGet", ["data/data.json"], (function(_this) {
+        return function(data) {
+          return Page.cmd("fileList", "data/img", function(files) {
+            var file, _i, _len, _results;
+            _results = [];
+            for (_i = 0, _len = files.length; _i < _len; _i++) {
+              file = files[_i];
+              if (file.indexOf("post_") !== 0) {
+                continue;
+              }
+              if (data.indexOf(file) === -1) {
+                _this.log("Deleting image", file, "...");
+                _results.push(_this.cmd("fileDelete", "data/img/" + file));
+              } else {
+                _results.push(void 0);
+              }
+            }
+            return _results;
+          });
+        };
+      })(this));
+    };
+
     ZeroBlog.prototype.onRequest = function(cmd, message) {
       if (cmd === "setSiteInfo") {
         return this.actionSetSiteInfo(message);
@@ -2688,4 +2828,4 @@
 
   window.Page = new ZeroBlog();
 
-}).call(this);
+}).call(this);