瀏覽代碼

新增快捷键操作

star7th 10 年之前
父節點
當前提交
9ae1dddb85

+ 4 - 2
Application/Home/View/Item/show.html

@@ -81,8 +81,8 @@
       <div class="doc-left-newbar">
 
         <if condition="$ItemPermn">
-          <div><a href="{:U('Home/Page/edit')}?item_id={$item.item_id}"><i class="icon-plus"></i>&nbsp;新建页面</a></div>
-          <div><a href="{:U('Home/Catalog/edit')}?item_id={$item.item_id}" ><i class="icon-folder-open"></i>新建目录</a></div>
+          <div><a href="{:U('Home/Page/edit')}?item_id={$item.item_id}&type=new" id="new-like"><i class="icon-plus"></i>&nbsp;新建页面</a></div>
+          <div><a href="{:U('Home/Catalog/edit')}?item_id={$item.item_id}" id="dir-like" ><i class="icon-folder-open"></i>新建目录</a></div>
 
         </if>
 
@@ -139,5 +139,7 @@
     <p>你可以复制地址给你的好友</p>
   </div>
 </div>
+<script src="__PUBLIC__/js/jquery.bootstrap-growl.min.js"></script>
+<script src="__PUBLIC__/js/jquery.hotkeys.js"></script>
 
 <script src="__PUBLIC__/js/item/show.js"></script>

+ 9 - 7
Application/Home/View/Page/edit.html

@@ -31,14 +31,14 @@
         <div class="head-left  pull-left">
             <ul class="inline">
                 <li>
-                    <input type="text" name="page_title" id="page_title" placeholder="请输入页面标题" value="{$page.page_title}">
+                    <input type="text" name="page_title" id="page_title" placeholder="请输入页面标题" value="{$page.page_title}" tabindex="1">
                 </li>
                 <li>
                     上级目录:
-                    <select name="cat_id" id="cat_id"></select>
+                    <select name="cat_id" id="cat_id" tabindex="2"></select>
                 </li>
                 <li>
-                    <input type="text" name="order" id="order" value="{$page.order}" placeholder="可选:顺序数字">
+                    <input type="text" name="order" id="order" value="{$page.order}" placeholder="可选:顺序数字"  tabindex="3" >
                 </li>
                 <li>
                     <!-- 首次添加没有历史版本,不显示 -->
@@ -51,17 +51,17 @@
         </div>
         <div class="head-right pull-right">
             <a href="#" class="btn btn-primary " id="save">保存</a>
-            <a href="../item/show?item_id={$item_id}&page_id={$page.page_id}" class="btn ">取消</a>
+            <a href="../item/show?item_id={$item_id}&page_id={$page.page_id}" class="btn cancel">取消</a>
         </div>
     </header>
     <br>
     <!-- 插入模板的按钮组 -->
     <div class="btns">
-        <button id="api-doc">插入API接口模板</button>
-        <button id="database-doc">插入数据字典模板</button>
+        <button id="api-doc" tabindex="4" >插入API接口模板</button>
+        <button id="database-doc" tabindex="5" >插入数据字典模板</button>
     </div>
     <div id="editormd">
-        <textarea id="page_content" style="display:none;">{$page.page_content}</textarea>
+        <textarea id="page_content" style="display:none;" tabindex="6" >{$page.page_content}</textarea>
     </div>
     <input type="hidden" id="item_id" value="{$item_id}">
     <input type="hidden" id="page_id" value="{$page.page_id}">
@@ -75,6 +75,8 @@
     <include file="MdTemplate/database" />
 </div>
 <include file="Common/footer" />
+<script src="__PUBLIC__/js/jquery.bootstrap-growl.min.js"></script>
+<script src="__PUBLIC__/js/jquery.hotkeys.js"></script>
 <script src="__PUBLIC__/editor.md/editormd.min.js"></script>
 <script src="__PUBLIC__/editor.md/plugins/image-dialog/image-dialog.js"></script>
 <script src="__PUBLIC__/editor.md/plugins/link-dialog/link-dialog.js"></script>

+ 30 - 1
Public/js/item/show.js

@@ -152,7 +152,36 @@ $(function(){
       return height
   }
 
-
+  var keyMap = {
+    // 编辑
+    "Ctrl+E": function() {
+      location.href = $("#edit-link").attr('href');
+    },
+    // 删除
+    "Ctrl+D": function() {
+      if (confirm('确认删除吗?'))
+        location.href = $("#delete-link").attr('href');
+    },
+    // 新建页面
+    "Ctrl+F1": function() {
+      location.href = $("#new-like").attr('href');
+    },
+    // 新建目录
+    "Ctrl+F2": function() {
+      location.href = $("#dir-like").attr('href');
+    }
+  };
+  if (!isMobile()) initKeys();
+  function initKeys() {
+    var $doc = $(document);
+    $.each(keyMap, function(key, fn) {
+      $doc.on('keydown', null, key, function(e) {
+        e.preventDefault();
+        fn();
+        return false;
+      });
+    });
+  }
     
 })
 

+ 1 - 0
Public/js/jquery.bootstrap-growl.min.js

@@ -0,0 +1 @@
+(function(){var c;c=jQuery;c.bootstrapGrowl=function(f,a){var b,e,d;a=c.extend({},c.bootstrapGrowl.default_options,a);b=c("<div>");b.attr("class","bootstrap-growl alert");a.type&&b.addClass("alert-"+a.type);a.allow_dismiss&&(b.addClass("alert-dismissible"),b.append('<button class="close" data-dismiss="alert" type="button"><span aria-hidden="true">&times;</span><span class="sr-only">Close</span></button>'));b.append(f);a.top_offset&&(a.offset={from:"top",amount:a.top_offset});d=a.offset.amount;c(".bootstrap-growl").each(function(){return d= Math.max(d,parseInt(c(this).css(a.offset.from))+c(this).outerHeight()+a.stackup_spacing)});e={position:"body"===a.ele?"fixed":"absolute",margin:0,"z-index":"9999",display:"none"};e[a.offset.from]=d+"px";b.css(e);"auto"!==a.width&&b.css("width",a.width+"px");c(a.ele).append(b);switch(a.align){case "center":b.css({left:"50%","margin-left":"-"+b.outerWidth()/2+"px"});break;case "left":b.css("left","20px");break;default:b.css("right","20px")}b.fadeIn();0<a.delay&&b.delay(a.delay).fadeOut(function(){return c(this).alert("close")}); return b};c.bootstrapGrowl.default_options={ele:"body",type:"info",offset:{from:"top",amount:20},align:"right",width:250,delay:4E3,allow_dismiss:!0,stackup_spacing:10}}).call(this);

+ 204 - 0
Public/js/jquery.hotkeys.js

@@ -0,0 +1,204 @@
+/*jslint browser: true*/
+/*jslint jquery: true*/
+
+/*
+ * jQuery Hotkeys Plugin
+ * Copyright 2010, John Resig
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ *
+ * Based upon the plugin by Tzury Bar Yochay:
+ * https://github.com/tzuryby/jquery.hotkeys
+ *
+ * Original idea by:
+ * Binny V A, http://www.openjs.com/scripts/events/keyboard_shortcuts/
+ */
+
+/*
+ * One small change is: now keys are passed by object { keys: '...' }
+ * Might be useful, when you want to pass some other data to your handler
+ */
+
+(function(jQuery) {
+
+  jQuery.hotkeys = {
+    version: "0.2.0",
+
+    specialKeys: {
+      8: "backspace",
+      9: "tab",
+      10: "return",
+      13: "return",
+      16: "shift",
+      17: "ctrl",
+      18: "alt",
+      19: "pause",
+      20: "capslock",
+      27: "esc",
+      32: "space",
+      33: "pageup",
+      34: "pagedown",
+      35: "end",
+      36: "home",
+      37: "left",
+      38: "up",
+      39: "right",
+      40: "down",
+      45: "insert",
+      46: "del",
+      59: ";",
+      61: "=",
+      96: "0",
+      97: "1",
+      98: "2",
+      99: "3",
+      100: "4",
+      101: "5",
+      102: "6",
+      103: "7",
+      104: "8",
+      105: "9",
+      106: "*",
+      107: "+",
+      109: "-",
+      110: ".",
+      111: "/",
+      112: "f1",
+      113: "f2",
+      114: "f3",
+      115: "f4",
+      116: "f5",
+      117: "f6",
+      118: "f7",
+      119: "f8",
+      120: "f9",
+      121: "f10",
+      122: "f11",
+      123: "f12",
+      144: "numlock",
+      145: "scroll",
+      173: "-",
+      186: ";",
+      187: "=",
+      188: ",",
+      189: "-",
+      190: ".",
+      191: "/",
+      192: "`",
+      219: "[",
+      220: "\\",
+      221: "]",
+      222: "'"
+    },
+
+    shiftNums: {
+      "`": "~",
+      "1": "!",
+      "2": "@",
+      "3": "#",
+      "4": "$",
+      "5": "%",
+      "6": "^",
+      "7": "&",
+      "8": "*",
+      "9": "(",
+      "0": ")",
+      "-": "_",
+      "=": "+",
+      ";": ": ",
+      "'": "\"",
+      ",": "<",
+      ".": ">",
+      "/": "?",
+      "\\": "|"
+    },
+
+    // excludes: button, checkbox, file, hidden, image, password, radio, reset, search, submit, url
+    textAcceptingInputTypes: [
+      "text", "password", "number", "email", "url", "range", "date", "month", "week", "time", "datetime",
+      "datetime-local", "search", "color", "tel"],
+
+    // default input types not to bind to unless bound directly
+    textInputTypes: /textarea|input|select/i,
+
+    options: {
+      filterInputAcceptingElements: true,
+      filterTextInputs: true,
+      filterContentEditable: true
+    }
+  };
+
+  function keyHandler(handleObj) {
+    if (typeof handleObj.data === "string") {
+      handleObj.data = {
+        keys: handleObj.data
+      };
+    }
+
+    // Only care when a possible input has been specified
+    if (!handleObj.data || !handleObj.data.keys || typeof handleObj.data.keys !== "string") {
+      return;
+    }
+
+    var origHandler = handleObj.handler,
+      keys = handleObj.data.keys.toLowerCase().split(" ");
+
+    handleObj.handler = function(event) {
+      //      Don't fire in text-accepting inputs that we didn't directly bind to
+      if (this !== event.target &&
+        (jQuery.hotkeys.options.filterInputAcceptingElements &&
+          jQuery.hotkeys.textInputTypes.test(event.target.nodeName) ||
+          (jQuery.hotkeys.options.filterContentEditable && jQuery(event.target).attr('contenteditable')) ||
+          (jQuery.hotkeys.options.filterTextInputs &&
+            jQuery.inArray(event.target.type, jQuery.hotkeys.textAcceptingInputTypes) > -1))) {
+        return;
+      }
+
+      var special = event.type !== "keypress" && jQuery.hotkeys.specialKeys[event.which],
+        character = String.fromCharCode(event.which).toLowerCase(),
+        modif = "",
+        possible = {};
+
+      jQuery.each(["alt", "ctrl", "shift"], function(index, specialKey) {
+
+        if (event[specialKey + 'Key'] && special !== specialKey) {
+          modif += specialKey + '+';
+        }
+      });
+
+      // metaKey is triggered off ctrlKey erronously
+      if (event.metaKey && !event.ctrlKey && special !== "meta") {
+        modif += "meta+";
+      }
+
+      if (event.metaKey && special !== "meta" && modif.indexOf("alt+ctrl+shift+") > -1) {
+        modif = modif.replace("alt+ctrl+shift+", "hyper+");
+      }
+
+      if (special) {
+        possible[modif + special] = true;
+      }
+      else {
+        possible[modif + character] = true;
+        possible[modif + jQuery.hotkeys.shiftNums[character]] = true;
+
+        // "$" can be triggered as "Shift+4" or "Shift+$" or just "$"
+        if (modif === "shift+") {
+          possible[jQuery.hotkeys.shiftNums[character]] = true;
+        }
+      }
+
+      for (var i = 0, l = keys.length; i < l; i++) {
+        if (possible[keys[i]]) {
+          return origHandler.apply(this, arguments);
+        }
+      }
+    };
+  }
+
+  jQuery.each(["keydown", "keyup", "keypress"], function() {
+    jQuery.event.special[this] = {
+      add: keyHandler
+    };
+  });
+
+})(jQuery || this.jQuery || window.jQuery);

+ 93 - 63
Public/js/page/edit.js

@@ -1,62 +1,94 @@
 var editormd;
 
+
 $(function() {
   /*加载目录*/
   getCatList();
 
-  function getCatList(){
-      var default_cat_id = $("#default_cat_id").val();
-      var item_id = $("#item_id").val();
-      $.get(
-        "../catalog/catList",
-        { "item_id": item_id },
-        function(data){
-          $("#cat_id").html('<OPTION value="0">无</OPTION>');
-          if (data.error_code == 0) {
-            json = data.data;
-            console.log(json);
-            for (var i = 0; i < json.length; i++) {
-                cat_html ='<OPTION value="'+json[i].cat_id+'" ';
-                if (default_cat_id == json[i].cat_id ) {
-                  cat_html += ' selected ';
-                }
-
-                cat_html +=' ">'+json[i].cat_name+'</OPTION>';
-                $("#cat_id").append(cat_html);
-            };
+  function getCatList() {
+    var default_cat_id = $("#default_cat_id").val();
+    var item_id = $("#item_id").val();
+    $.get(
+      "../catalog/catList", {
+        "item_id": item_id
+      },
+      function(data) {
+        $("#cat_id").html('<OPTION value="0">无</OPTION>');
+        if (data.error_code == 0) {
+          json = data.data;
+          console.log(json);
+          for (var i = 0; i < json.length; i++) {
+            cat_html = '<OPTION value="' + json[i].cat_id + '" ';
+            if (default_cat_id == json[i].cat_id) {
+              cat_html += ' selected ';
+            }
+
+            cat_html += ' ">' + json[i].cat_name + '</OPTION>';
+            $("#cat_id").append(cat_html);
           };
-          
-        },
-        "json"
+        };
+
+      },
+      "json"
 
-        );
+    );
   }
+
+  var keyMap = {
+    // 保存
+    "Ctrl-S": function() {
+      $("#save").click();
+    }
+  };
+  initEditorOutsideKeys();
+
+  function initEditorOutsideKeys() {
+    if (!editormd) return;
+    var $doc = $(document);
+    $.each(keyMap, function(key, fn) {
+      $doc.on('keydown', null, key.replace('-', '+'), function(e) {
+        e.preventDefault();
+        fn();
+      });
+    });
+  }
+  // 如果是新增页面,则光标为标题文本框
+  if (location.href.indexOf('type=new') !== -1) {
+    setTimeout(function() {
+      $('#page_title').focus();
+    }, 1000);
+  }
+
   /*初始化编辑器*/
   editormd = editormd("editormd", {
-      width   : "90%",
-      height  : 1000,
-      syncScrolling : "single",
-      path    : DocConfig.pubile + "/editor.md/lib/" ,
-      placeholder : "本编辑器支持Markdown编辑,左边编写,右边预览",
-      imageUpload : true,
-      imageFormats : ["jpg", "jpeg", "gif", "png", "bmp", "webp","JPG", "JPEG", "GIF", "PNG", "BMP", "WEBP"],
-      imageUploadURL : "uploadImg",
-
+    width: "90%",
+    height: 1000,
+    syncScrolling: "single",
+    path: DocConfig.pubile + "/editor.md/lib/",
+    placeholder: "本编辑器支持Markdown编辑,左边编写,右边预览",
+    imageUpload: true,
+    imageFormats: ["jpg", "jpeg", "gif", "png", "bmp", "webp", "JPG", "JPEG", "GIF", "PNG", "BMP", "WEBP"],
+    imageUploadURL: "uploadImg",
+    onload: function() {
+      this.addKeyMap(keyMap);
+    }
   });
 
   /*插入API接口模板*/
-  $("#api-doc").click(function(){
-      var tmpl = $("#api-doc-templ").html();
-      editormd.insertValue(tmpl);
+  $("#api-doc").click(function() {
+    var tmpl = $("#api-doc-templ").html();
+    editormd.insertValue(tmpl);
   });
   /*插入数据字典模板*/
-  $("#database-doc").click(function(){
-      var tmpl = $("#database-doc-templ").html();
-      editormd.insertValue(tmpl);
+  $("#database-doc").click(function() {
+    var tmpl = $("#database-doc-templ").html();
+    editormd.insertValue(tmpl);
   });
-  
+
   /*保存*/
-  $("#save").click(function(){
+  var saving = false;
+  $("#save").click(function() {
+    if (saving) return false;
     var page_id = $("#page_id").val();
     var item_id = $("#item_id").val();
     var cat_id = $("#cat_id").val();
@@ -64,32 +96,30 @@ $(function() {
     var page_content = $("#page_content").val();
     var item_id = $("#item_id").val();
     var order = $("#order").val();
+    saving = true;
     $.post(
-      "save",
-      {"page_id":page_id ,"cat_id":cat_id ,"order":order ,"page_content":page_content,"page_title":page_title,"item_id":item_id },
-      function(data){
-          if (data.error_code == 0) {
-            alert("保存成功!");
-            window.location.href="../item/show?page_id="+data.data.page_id+"&item_id="+item_id;
-          }else{
-            alert("保存失败!");
-
-          }
+      "save", {
+        "page_id": page_id,
+        "cat_id": cat_id,
+        "order": order,
+        "page_content": page_content,
+        "page_title": page_title,
+        "item_id": item_id
+      },
+      function(data) {
+        if (data.error_code == 0) {
+          $.bootstrapGrowl("保存成功!");
+          window.location.href = "../item/show?page_id=" + data.data.page_id + "&item_id=" + item_id;
+        } else {
+          $.bootstrapGrowl("保存失败!");
+
+        }
+        saving = false;
       },
       'json'
-      )
+    )
   })
 
 
-});
-
-
-
-
-
-
-
-
-
-
 
+});