Browse Source

右键菜单支持任意配置

zxlie 7 years ago
parent
commit
785b1cf8cf

+ 134 - 161
apps/background/index.js

@@ -220,15 +220,17 @@ var BgPageInstance = (function () {
             callback && callback(feHelper.ajaxDebuggerMgr[tab.id]);
 
             if (withAlert) {
+                let msg = '';
                 if (feHelper.ajaxDebuggerMgr[tab.id]) {
-                    let msg = '';
                     if (devToolsDetected) {
                         msg = 'DevTools已打开,确保已切换到【Console】界面,并关注信息输出,愉快的进行Ajax Debugger!'
                     } else {
                         msg = '请打开DevTools,并切换到【Console】界面,关注信息输出,愉快的进行Ajax Debugger!';
                     }
-                    alert(msg);
+                } else {
+                    msg = '已停止当前页面的Ajax Debugger功能!';
                 }
+                alert(msg);
             }
         });
     };
@@ -271,177 +273,144 @@ var BgPageInstance = (function () {
     };
 
     /**
-     * 创建扩展专属的右键菜单
+     * 右键菜单创建工具
+     * @param menuList
+     * @private
      */
-    let _createContextMenu = function () {
-        _removeContextMenu();
-        feHelper.contextMenuId = chrome.contextMenus.create({
-            title: "FeHelper工具",
-            contexts: ['page', 'selection', 'editable', 'link', 'image'],
-            documentUrlPatterns: ['http://*/*', 'https://*/*', 'file://*/*']
-        });
+    let _contextMenuCreator = function (menuList) {
+        let menus = Settings.getMenuOpts();
 
-        // 网页编码设置的menu
-        PageEncoding.createMenu(feHelper.contextMenuId);
-
-        chrome.contextMenus.create({
-            type: 'separator',
-            contexts: ['all'],
-            parentId: feHelper.contextMenuId
-        });
-        chrome.contextMenus.create({
-            title: "▣  二维码生成",
-            contexts: ['page', 'selection', 'editable', 'link', 'image'],
-            parentId: feHelper.contextMenuId,
-            onclick: function (info, tab) {
-                chrome.tabs.executeScript(tab.id, {
-                    code: '(' + (function (pInfo) {
-                        let linkUrl = pInfo.linkUrl;
-                        let pageUrl = pInfo.pageUrl;
-                        let imgUrl = pInfo.srcUrl;
-                        let selection = pInfo.selectionText;
-
-                        return linkUrl || imgUrl || selection || pageUrl;
-                    }).toString() + ')(' + JSON.stringify(info) + ')',
-                    allFrames: false
-                }, function (txt) {
-                    _openFileAndRun(tab, MSG_TYPE.QR_CODE, (typeof txt === 'object') ? txt[0] : txt);
-                });
-            }
-        });
+        menuList.forEach(m => {
+            if (m === 'MENU_PAGE_ENCODING') {
+                // 网页编码设置的menu
+                PageEncoding.createMenu(feHelper.contextMenuId, menus.MENU_PAGE_ENCODING);
+            } else {
+                let onClick = {
+                    MENU_QRCODE_CREATE: function (info, tab) {
+                        chrome.tabs.executeScript(tab.id, {
+                            code: '(' + (function (pInfo) {
+                                let linkUrl = pInfo.linkUrl;
+                                let pageUrl = pInfo.pageUrl;
+                                let imgUrl = pInfo.srcUrl;
+                                let selection = pInfo.selectionText;
+
+                                return linkUrl || imgUrl || selection || pageUrl;
+                            }).toString() + ')(' + JSON.stringify(info) + ')',
+                            allFrames: false
+                        }, function (txt) {
+                            _openFileAndRun(tab, MSG_TYPE.QR_CODE, (typeof txt === 'object') ? txt[0] : txt);
+                        });
+                    },
 
-        chrome.contextMenus.create({
-            type: 'separator',
-            contexts: ['image'],
-            parentId: feHelper.contextMenuId
-        });
-        chrome.contextMenus.create({
-            title: "◈  二维码解码",
-            contexts: ['image'],
-            parentId: feHelper.contextMenuId,
-            onclick: function (info, tab) {
-                _qrDecode(info, tab);
-            }
-        });
+                    MENU_QRCODE_DECODE: function (info, tab) {
+                        _qrDecode(info, tab);
+                    },
 
+                    MENU_PAGE_CAPTURE: function (info, tab) {
+                        PageCapture.full(tab);
+                    },
+                    MENU_COLOR_PICKER: function (info, tab) {
+                        _showColorPicker();
+                    },
+                    MENU_STR_ENDECODE: function (info, tab) {
+                        chrome.tabs.executeScript(tab.id, {
+                            code: '(' + (function (pInfo) {
+
+                                return pInfo.selectionText;
+                            }).toString() + ')(' + JSON.stringify(info) + ')',
+                            allFrames: false
+                        }, function (txt) {
+                            _openFileAndRun(tab, MSG_TYPE.EN_DECODE, (typeof txt === 'object') ? txt[0] : txt);
+                        });
+                    },
+                    MENU_JSON_FORMAT: function (info, tab) {
+                        chrome.tabs.executeScript(tab.id, {
+                            code: '(' + (function (pInfo) {
+                                return pInfo.selectionText;
+                            }).toString() + ')(' + JSON.stringify(info) + ')',
+                            allFrames: false
+                        }, function (txt) {
+                            _openFileAndRun(tab, MSG_TYPE.JSON_FORMAT, (typeof txt === 'object') ? txt[0] : txt);
+                        });
+                    },
+                    MENU_CODE_FORMAT: function (info, tab) {
+                        chrome.tabs.executeScript(tab.id, {
+                            code: '(' + (function (pInfo) {
+                                return pInfo.selectionText;
+                            }).toString() + ')(' + JSON.stringify(info) + ')',
+                            allFrames: false
+                        }, function (txt) {
+                            _openFileAndRun(tab, MSG_TYPE.CODE_BEAUTIFY, (typeof txt === 'object') ? txt[0] : txt);
+                        });
+                    },
+                    MENU_AJAX_DEBUGGER: function (info, tab) {
+                        _debuggerSwitchOn(() => {
+                            _tellDevToolsDbgSwitchOn(null, true);
+                        });
+                    },
 
-        chrome.contextMenus.create({
-            type: 'separator',
-            contexts: ['image'],
-            parentId: feHelper.contextMenuId
-        });
-        chrome.contextMenus.create({
-            title: "♛  图片转Base64",
-            contexts: ['image'],
-            parentId: feHelper.contextMenuId,
-            onclick: function (info, tab) {
-                _openFileAndRun(tab, MSG_TYPE.IMAGE_BASE64, info.srcUrl);
-            }
-        });
+                    MENU_CODE_STANDARD: function (info, tab) {
+                        _doFcpDetect(tab);
+                    },
+                    MENU_IMAGE_BASE64: function (info, tab) {
+                        _openFileAndRun(tab, MSG_TYPE.IMAGE_BASE64, info.srcUrl);
+                    },
+                    MENU_JSON_COMPARE: function (info, tab) {
+                        _openFileAndRun(tab, MSG_TYPE.JSON_COMPARE);
+                    },
+                    MENU_CODE_COMPRESS: function (info, tab) {
+                        _openFileAndRun(tab, MSG_TYPE.CODE_COMPRESS);
+                    },
+                    MENU_PAGE_OPTIMI: function (info, tab) {
+                        _openFileAndRun(tab, MSG_TYPE.SHOW_PAGE_LOAD_TIME);
+                    },
+                    MENU_TIME_STAMP: function (info, tab) {
+                        _openFileAndRun(tab, MSG_TYPE.TIME_STAMP);
+                    },
+                    MENU_RANDOM_PASS: function (info, tab) {
+                        _openFileAndRun(tab, MSG_TYPE.RANDOM_PASSWORD);
+                    },
+                    MENU_JS_REGEXP: function (info, tab) {
+                        _openFileAndRun(tab, MSG_TYPE.REGEXP_TOOL);
+                    },
+                    MENU_MARKDOWN_TL: function (info, tab) {
+                        _openFileAndRun(tab, MSG_TYPE.HTML_TO_MARKDOWN);
+                    },
+                    MENU_STICKY_NOTE: function (info, tab) {
+                        _openFileAndRun(tab, MSG_TYPE.STICKY_NOTES);
+                    }
+                };
 
-        chrome.contextMenus.create({
-            type: 'separator',
-            contexts: ['all'],
-            parentId: feHelper.contextMenuId
-        });
-        chrome.contextMenus.create({
-            title: "♨  字符串编解码",
-            contexts: ['page', 'selection', 'editable'],
-            parentId: feHelper.contextMenuId,
-            onclick: function (info, tab) {
-                chrome.tabs.executeScript(tab.id, {
-                    code: '(' + (function (pInfo) {
-
-                        return pInfo.selectionText;
-                    }).toString() + ')(' + JSON.stringify(info) + ')',
-                    allFrames: false
-                }, function (txt) {
-                    _openFileAndRun(tab, MSG_TYPE.EN_DECODE, (typeof txt === 'object') ? txt[0] : txt);
+                chrome.contextMenus.create({
+                    title: menus[m].icon + '  ' + menus[m].text,
+                    contexts: menus[m].contexts || ['all'],
+                    parentId: feHelper.contextMenuId,
+                    onclick: onClick[m]
                 });
-            }
-        });
-        chrome.contextMenus.create({
-            type: 'separator',
-            contexts: ['all'],
-            parentId: feHelper.contextMenuId
-        });
-        chrome.contextMenus.create({
-            title: "★  JSON格式化",
-            contexts: ['page', 'selection', 'editable'],
-            parentId: feHelper.contextMenuId,
-            onclick: function (info, tab) {
-                chrome.tabs.executeScript(tab.id, {
-                    code: '(' + (function (pInfo) {
-                        return pInfo.selectionText;
-                    }).toString() + ')(' + JSON.stringify(info) + ')',
-                    allFrames: false
-                }, function (txt) {
-                    _openFileAndRun(tab, MSG_TYPE.JSON_FORMAT, (typeof txt === 'object') ? txt[0] : txt);
-                });
-            }
-        });
-        chrome.contextMenus.create({
-            type: 'separator',
-            contexts: ['all'],
-            parentId: feHelper.contextMenuId
-        });
-        chrome.contextMenus.create({
-            title: "☂  代码格式化",
-            contexts: ['page', 'selection', 'editable'],
-            parentId: feHelper.contextMenuId,
-            onclick: function (info, tab) {
-                chrome.tabs.executeScript(tab.id, {
-                    code: '(' + (function (pInfo) {
-                        return pInfo.selectionText;
-                    }).toString() + ')(' + JSON.stringify(info) + ')',
-                    allFrames: false
-                }, function (txt) {
-                    _openFileAndRun(tab, MSG_TYPE.CODE_BEAUTIFY, (typeof txt === 'object') ? txt[0] : txt);
-                });
-            }
-        });
 
-        chrome.contextMenus.create({
-            type: 'separator',
-            contexts: ['all'],
-            parentId: feHelper.contextMenuId
-        });
-        chrome.contextMenus.create({
-            title: "☀  页面取色器",
-            contexts: ['page', 'selection', 'editable'],
-            parentId: feHelper.contextMenuId,
-            onclick: function (info, tab) {
-                _showColorPicker();
             }
         });
+    };
 
-        chrome.contextMenus.create({
-            type: 'separator',
-            contexts: ['all'],
-            parentId: feHelper.contextMenuId
-        });
-        chrome.contextMenus.create({
-            title: "✂  网页滚动截屏",
-            contexts: ['all'],
-            parentId: feHelper.contextMenuId,
-            onclick: function (info, tab) {
-                PageCapture.full(tab);
-            }
+    /**
+     * 创建扩展专属的右键菜单
+     */
+    let _createContextMenu = function () {
+        _removeContextMenu();
+        feHelper.contextMenuId = chrome.contextMenus.create({
+            title: "FeHelper工具",
+            contexts: ['page', 'selection', 'editable', 'link', 'image'],
+            documentUrlPatterns: ['http://*/*', 'https://*/*', 'file://*/*']
         });
 
-        chrome.contextMenus.create({
-            type: 'separator',
-            contexts: ['all'],
-            parentId: feHelper.contextMenuId
-        });
-        chrome.contextMenus.create({
-            title: "▤  我的便签笔记",
-            contexts: ['all'],
-            parentId: feHelper.contextMenuId,
-            onclick: function (info, tab) {
-                _openFileAndRun(tab, MSG_TYPE.STICKY_NOTES);
-            }
-        });
+        if (!Settings.didMenuSettingSaved()) {
+            _contextMenuCreator(Settings.getDefaultContextMenus());
+        } else {
+            Settings.getOptsFromBgPage((opts) => {
+                _contextMenuCreator(Object.keys(opts).filter(m => /^MENU_/.test(m)));
+            });
+        }
+
     };
 
     /**
@@ -580,7 +549,7 @@ var BgPageInstance = (function () {
                     type: MSG_TYPE.JSON_PAGE_FORMAT,
                     options: {
                         MAX_JSON_KEYS_NUMBER: opts.MAX_JSON_KEYS_NUMBER,
-                        AUTO_TEXT_DECODE:opts.AUTO_TEXT_DECODE === 'true'
+                        AUTO_TEXT_DECODE: opts.AUTO_TEXT_DECODE === 'true'
                     }
                 });
             });
@@ -648,6 +617,10 @@ var BgPageInstance = (function () {
                     autoClose: 2000
                 });
             }
+            // 判断菜单是否保存过
+            else if(request.type === MSG_TYPE.MENU_SAVED){
+                Settings.didMenuSettingSaved(callback);
+            }
             //判断是否可以针对json页面进行自动格式化
             else if (request.type === MSG_TYPE.JSON_PAGE_FORMAT_REQUEST) {
                 _jsonAutoFormatRequest();

+ 1 - 1
apps/manifest.json

@@ -1,6 +1,6 @@
 {
   "name": "WEB前端助手(FeHelper)",
-  "version": "2018.11.1217",
+  "version": "2018.11.1911",
   "manifest_version": 2,
   "default_locale": "zh_CN",
   "description": "FE助手:包括JSON格式化、二维码生成与解码、信息编解码、代码压缩、美化、页面取色、Markdown与HTML互转、网页滚动截屏、正则表达式、时间转换工具、编码规范检测、页面性能检测、Ajax接口调试、密码生成器、JSON比对工具、网页编码设置、便签笔记",

+ 59 - 3
apps/options/index.css

@@ -2,7 +2,7 @@
 @import "../popup/index.css";
 
 .wrapper {
-    width:900px;
+    width:940px;
 }
 #pageContainer label {
     font-weight: normal;
@@ -49,13 +49,69 @@ h5,h4 {
     display: inline-block;
     padding: 4px 10px;
 }
-.box-inner.x-disabled {
+.x-disabled {
     opacity: 0.2;
 }
+.x-disabled .box-mpreview ul.x-menus li:hover {
+    background-color: transparent;
+    color: inherit;
+}
 .row-line {
     line-height: 24px;
 }
 .box-preview {
     position: relative;
-    top:-145px;
+    left: 10px;
+    top: -40px;
+    border-left: 1px solid #f1f1f1;
+    padding-left: 24px;
+    width: 300px;
+}
+.ul-menu {
+    width: 550px;
+    list-style: none;
+    user-select: none;
+}
+.ul-menu li {
+    float: left;
+    width: 160px;
+}
+.ct-menu {
+    position: relative;
+}
+.ct-popup .ct-fun{
+    width: 550px;
+}
+.box-mpreview {
+    position: relative;
+    left: 560px;
+    top: -407px;
+    width: 450px;
+    margin-bottom: -547px;
+    border-left: 1px solid #f1f1f1;
+    user-select:none;
+}
+.box-mpreview h5 {
+    margin: 0 0 -10px 20px;
+}
+.box-mpreview ul.x-menus {
+    position: relative;
+    top: -145px;
+    left: 210px;
+    background: #f2f2f2;
+    border: 1px solid #bbb;
+    border-radius: 4px;
+    padding: 3px 0;
+    list-style: none;
+    width: 160px;
+}
+.box-mpreview ul.x-menus li {
+    padding: 2px 20px;
+    font-weight: 500;
+    font-size: 14px;
+}
+.box-mpreview ul.x-menus li:hover {
+    background-color: #276cf9;
+    color: #fff;
+    cursor: default;
 }

File diff suppressed because it is too large
+ 0 - 0
apps/options/index.html


+ 20 - 4
apps/options/index.js

@@ -9,20 +9,36 @@ new Vue({
     data: {
         selectedOpts: [],
         maxJsonKeysNumber: 0,
-        auto_text_decode:false,
-        manifest: {}
+        auto_text_decode: false,
+        manifest: {},
+        menuOpts: {},
+        selectedMenu: [],
+        defaultMenu: Settings.getDefaultContextMenus()
     },
 
     created: function () {
 
         Settings.getOptions((opts) => {
             this.selectedOpts = Object.keys(opts).filter(k => {
-                return typeof(opts[k]) === 'string' && !['MAX_JSON_KEYS_NUMBER','AUTO_TEXT_DECODE'].includes(k)
+                if (typeof(opts[k]) === 'string' && /^MENU_/.test(k)) {
+                    this.selectedMenu.push(k);
+                    return false;
+                }
+                return typeof(opts[k]) === 'string' && !['MAX_JSON_KEYS_NUMBER', 'AUTO_TEXT_DECODE'].includes(k)
             });
+
             this.maxJsonKeysNumber = opts['MAX_JSON_KEYS_NUMBER'];
             this.auto_text_decode = opts['AUTO_TEXT_DECODE'] === 'true';
+
+            // 如果还没设置过menu,就用默认的了
+            Settings.askMenuSavedOrNot(saved => {
+                if (!saved) {
+                    this.selectedMenu = this.defaultMenu;
+                }
+            });
         });
         this.manifest = chrome.runtime.getManifest();
+        this.menuOpts = Settings.getMenuOpts();
     },
 
     methods: {
@@ -42,7 +58,7 @@ new Vue({
             Settings.setOptions(this.selectedOpts.concat([
                 {MAX_JSON_KEYS_NUMBER: parseInt(this.maxJsonKeysNumber, 10)},
                 {AUTO_TEXT_DECODE: String(this.auto_text_decode)},
-            ]));
+            ]).concat(this.selectedMenu));
 
             setTimeout(() => {
                 this.close();

BIN
apps/options/menu-bg.png


+ 146 - 4
apps/options/settings.js

@@ -36,12 +36,99 @@ module.exports = (() => {
         'STICKY_NOTES'
     ];
 
+    // 邮件菜单配置项
+    let menuOptions = {
+        MENU_PAGE_ENCODING: {
+            icon: '↺',
+            text: '网页编码设置'
+        },
+        MENU_QRCODE_CREATE: {
+            icon: '▣',
+            text: '二维码生成器',
+            contexts: ['page', 'selection', 'editable', 'link', 'image']
+        },
+        MENU_QRCODE_DECODE: {
+            icon: '◈',
+            text: '二维码解码器',
+            contexts: ['image']
+        },
+        MENU_PAGE_CAPTURE: {
+            icon: '✂',
+            text: '页面滚动截屏'
+        },
+        MENU_COLOR_PICKER: {
+            icon: '☀',
+            text: '页面取色工具',
+            contexts: ['page', 'selection', 'editable']
+        },
+        MENU_IMAGE_BASE64: {
+            icon: '⇄',
+            text: '图片与base64',
+            contexts: ['image']
+        },
+        MENU_STR_ENDECODE: {
+            icon: '♨',
+            text: '字符串编解码',
+            contexts: ['page', 'selection', 'editable']
+        },
+        MENU_JSON_FORMAT: {
+            icon: '★',
+            text: 'JSON格式化',
+            contexts: ['page', 'selection', 'editable']
+        },
+        MENU_JSON_COMPARE: {
+            icon: '☃',
+            text: 'JSON比对器'
+        },
+        MENU_CODE_FORMAT: {
+            icon: '☂',
+            text: '代码美化工具',
+            contexts: ['page', 'selection', 'editable']
+        },
+        MENU_CODE_COMPRESS: {
+            icon: '〓',
+            text: '代码压缩工具'
+        },
+        MENU_AJAX_DEBUGGER: {
+            icon: '▶',
+            text: 'Ajax调试功能'
+        },
+        MENU_PAGE_OPTIMI: {
+            icon: '√',
+            text: '页面性能检测'
+        },
+        MENU_TIME_STAMP: {
+            icon: '♖',
+            text: '时间(戳)转换'
+        },
+        MENU_RANDOM_PASS: {
+            icon: '☽',
+            text: '随机密码生成'
+        },
+        MENU_JS_REGEXP: {
+            icon: '✙',
+            text: 'JS正则表达式'
+        },
+        MENU_MARKDOWN_TL: {
+            icon: 'ⓜ',
+            text: 'markown工具'
+        },
+        MENU_CODE_STANDARD: {
+            icon: '☊',
+            text: '编码规范检测'
+        },
+        MENU_STICKY_NOTE: {
+            icon: '▤',
+            text: '我的便签笔记'
+        }
+    };
+
     /**
      * 获取全部配置项
      * @returns {string[]}
      * @private
      */
-    let _getAllOpts = () => optionItems;
+    let _getAllOpts = () => optionItems.concat(Object.keys(menuOptions));
 
 
     /**
@@ -72,7 +159,7 @@ module.exports = (() => {
     let _getOptsFromBgPage = function (callback) {
         if (callback && typeof callback === 'function') {
             let rst = {};
-            optionItems.forEach((item) => {
+            _getAllOpts().forEach((item) => {
                 let opt = localStorage.getItem(item);
                 if (item === 'MAX_JSON_KEYS_NUMBER') {
                     rst[item] = opt || maxJsonKeysNumber;
@@ -92,7 +179,7 @@ module.exports = (() => {
      */
     let _setOptsFromBgPage = function (items) {
 
-        optionItems.forEach((opt) => {
+        _getAllOpts().forEach((opt) => {
             let found = items.some(it => {
                 if (typeof(it) === 'string' && it === opt) {
                     localStorage.setItem(opt, 'true');
@@ -110,11 +197,66 @@ module.exports = (() => {
         });
     };
 
+    /**
+     * 获取菜单配置项
+     */
+    let _getMenuOpts = function () {
+        return menuOptions;
+    };
+
+    /**
+     * 询问一下,菜单是否已保存
+     * @param callback
+     * @private
+     */
+    let _askMenuSavedOrNot = function (callback) {
+        chrome.runtime.sendMessage({
+            type: MSG_TYPE.MENU_SAVED
+        }, callback);
+    };
+
+    /**
+     * 判断menu是否已经设置过了,判断方法是:
+     * 随便挑选一个Menu项,看它是否在localStorage中被存储过了
+     * @private
+     */
+    let _didMenuSettingSaved = function (callback) {
+        let flag = !!localStorage.getItem('MENU_PAGE_ENCODING');
+        if (callback && typeof callback === 'function') {
+            callback(flag);
+        } else {
+            return flag;
+        }
+    };
+
+    /**
+     * 默认的菜单列表
+     * @returns {string[]}
+     * @private
+     */
+    let _getDefaultContextMenus = function () {
+        return [
+            'MENU_PAGE_ENCODING',
+            'MENU_QRCODE_CREATE',
+            'MENU_QRCODE_DECODE',
+            'MENU_PAGE_CAPTURE',
+            'MENU_COLOR_PICKER',
+            'MENU_IMAGE_BASE64',
+            'MENU_STR_ENDECODE',
+            'MENU_JSON_FORMAT',
+            'MENU_CODE_FORMAT'
+        ];
+    };
+
     return {
         getAllOpts: _getAllOpts,
         setOptsFromBgPage: _setOptsFromBgPage,
         getOptsFromBgPage: _getOptsFromBgPage,
         getOptions: _getOptions,
-        setOptions: _setOptions
+        setOptions: _setOptions,
+        getMenuOpts: _getMenuOpts,
+        didMenuSettingSaved: _didMenuSettingSaved,
+        getDefaultContextMenus: _getDefaultContextMenus,
+        askMenuSavedOrNot: _askMenuSavedOrNot
     };
 })();

+ 3 - 3
apps/page-encoding/index.js

@@ -43,11 +43,11 @@ let PageEncoding = (() => {
     /**
      * 创建右键菜单
      */
-    let createMenu = (parentMenuId) => {
+    let createMenu = (parentMenuId, menuConfig) => {
 
         let encodingMenu = chrome.contextMenus.create({
-            title: "♨  网页编码设置",
-            contexts: ["all"],
+            title: menuConfig.icon + '  ' + menuConfig.text,
+            contexts: menuConfig.contexts || ["all"],
             documentUrlPatterns: ['http://*/*', 'https://*/*', 'file://*/*'],
             parentId: parentMenuId
         });

+ 9 - 2
apps/qr-code/decode.js

@@ -15,11 +15,18 @@ module.exports = (() => {
                 '<textarea style="display:block;border-radius:5px 5px;width:398px;border:1px solid #aaa;min-height:80px;resize:none;box-shadow:2px 2px 5px #aaa;padding:10px;font-size:14px;color:#888;"></textarea>' +
                 '<div style="margin-top:10px;">' +
                 '<span id="__fehelper_qr_msg_" style="float: right;color:#f00;display:none;">复制成功!</span>' +
-                '<a id="__fehelper_qr_copy_" style="margin-right:20px;color: #00f;text-decoration: underline" href="#">复制</a>' +
-                '<a id="__fehelper_qr_close_" style="margin-top:10px;color: #00f;text-decoration: underline" href="#">关闭</a>' +
+                '<a id="__fehelper_qr_open_" style="margin-right:20px;color: #00f;text-decoration: underline;display: inline;" href="#">打开</a>' +
+                '<a id="__fehelper_qr_copy_" style="margin-right:20px;color: #00f;text-decoration: underline;display: inline;" href="#">复制</a>' +
+                '<a id="__fehelper_qr_close_" style="margin-top:10px;color: #00f;text-decoration: underline;display: inline" href="#">关闭</a>' +
                 '</div></div>' +
                 '</div>').appendTo('body');
 
+
+            el.find('a#__fehelper_qr_open_').click(function (e) {
+                e.preventDefault();
+                window.open(el.find('textarea').val());
+            });
+
             el.find('a#__fehelper_qr_copy_').click(function (e) {
                 e.preventDefault();
 

+ 1 - 1
apps/static/css/bootstrap.min.css

@@ -68,6 +68,6 @@ body {
 textarea{
     resize: vertical;
 }
-a.x-a-high {
+a.x-a-high, a.x-a-high:visited {
     color:blue;
 }

+ 2 - 0
apps/static/js/msg_type.js

@@ -35,6 +35,8 @@ const MSG_TYPE = {
     GET_OPTIONS: 'get_options',
     //set options
     SET_OPTIONS: 'set_options',
+    // MENU SAVED
+    MENU_SAVED: 'menu_saved',
 
     //启动项
     START_OPTION: 'start-option',

BIN
apps/static/screenshot/wx-qrcode-fehelper-group.png


+ 1 - 1
apps/sticky-notes/html5sticky.js

@@ -240,7 +240,7 @@ html5sticky.getNotes = function () {
 
         // set width and height of the sticky note
         $('.note_common').css({width: stickywidth + 'px', height: stickyheight + 'px'});
-        $('.note_common p').css({height: (stickyheight - 60) + 'px', width: (stickywidth + 9) + 'px'});
+        $('.note_common p').css({height: (stickyheight - 60) + 'px', width: (stickywidth - 24) + 'px'});
 
     });
 };

Some files were not shown because too many files changed in this diff