IndexDB + 码云 + 谷歌插件 = ?

一.需求

  • 能够“极速”到达的笔记本,在需要的时候以最快速度打开。
  • 书签,即收藏网站。

二.痛点

以下痛点仅代表个人

  • 在哪记录代码片段,以及其他它要记录的文字?

在做某个项目的过程中,如果想临时记录某个接口的返回值,字段,或者随手复制项目中一段没看懂的代码,便于有空复习。

项目目录如下:

dist/
src/
    .gitignore
    index.html
    package.json
    webpack.config.js

即项目中的目录都是有意义的。通常我这样做:

  1. 在项目中临时新建一个文件记录,那务必记得在 git 提交之前删除。毕竟是公司项目,新建一个‘私人’的文件不太合适。
  2. 本地电脑某个文件夹用作自己的笔记本,要记录时打开编辑器进行记录。缺点是,除了项目本身的编辑器,还得额外开一个编辑器做笔记,同时第二天要看笔记的时候得用编辑器再次打开笔记本。
  • 如何收藏网站?

谷歌浏览器书签收藏,谷歌浏览器登录后支持书签同步,之后更换电脑重装系统都能找回原有的书签。

  1. 没有梯子时登录不了谷歌账户,以往收藏的网站就都没了。当然可以将书签导出成文件,需要的时候再将文件还原为书签。
  2. 使用火狐浏览器,火狐不用梯子也能登录,能导出书签并还原。仅有的缺点是,它不是Chrome浏览器

三.寻找解决方案

要求:

  1. 要能做笔记,笔记持久化存储。
  2. 不能破坏原有项目结构。
  3. 不打开额外软件。
  4. 笔记页面‘快速’到达。
  5. 收藏的网站书签持久化存储,‘快速’到达。

分析

  1. 浏览器算是前端开发中保持打开的软件,如果以网页 tab 的形式打开笔记进行编辑,不会觉得是额外的操作。
  2. 目前有很多在线的优秀笔记工具,例如印象笔记等,提供记录编辑功能。
  3. 掘金Chrome插件,重写浏览器new tab页面,在浏览器新建标签页时最高效的获取用户注意。
  4. IndexedDB,Chrome 中的数据库,可用于存储数据。
  5. 码云提供免费的静态资源托管服务。

结论

  1. 写个编辑器网页MarkNote,页面中能进行文字的编辑书写,利用 IndexedDB 进行数据的保存,下次打开页面时将保存的数据显示在页面上。
  2. 将编辑器网页托管到码云上,写个Chrome插件,利用插件将码云上的编辑器网页绑定到浏览器右键菜单,即可通过在任意网页上右键打开编辑器网页进行记录笔记。
  3. 在码云中新建config.json文件保存自己常用网站信息,利用插件重写浏览器的新建标签页,在标签页中请求config.json文件获得书签信息生成属于自己的网站导航

四.如何实现

4.1 谷歌插件实现

4.1.1 目录结构

_locales/
html/
    css/
        newtab.css
    js/
        jquery.js
        background.js
        newtab.js
    newtab.html
    background.html
manifest.json

4.1.2 manifest.json配置文件核心

{
  "manifest_version": 2,
  "name": "工作笔记",
  "version": "1.0.0",
  "description": "工作笔记谷歌插件",
  "homepage_url": "https://yesiam.gitee.io/marknote/", // 插件首页地址 
  "chrome_url_overrides": {
    "newtab": "./html/newtab.html"   // 重写 新建标签页为 "./html/newtab.html"
  },
  "background": {
    "page": "./html/background.html"  // 在该页面编写脚本 添加右键菜单
  },
  "permissions": [   // 权限申请
    "contextMenus",
    "tabs",
    "notifications",
    "webRequest",
    "webRequestBlocking",
    "storage",
    "http://*/*",
    "https://*/*"
  ],
  "default_locale": "zh_CN"
}

4.1.3 newtab 新建标签页实现

newtab.html

<link rel="stylesheet" href="./css/newtab.css">
<title>工作笔记</title>

<body>
  <div id="main">
  </div>
  <script src="./js/jquery.js"></script>
  <script src="./js/newtab.js"></script>
</body>

newtab.js

function Tab(data){
  this.data = data.newtab;
  this.parent = '#main';
}
Tab.prototype.init = function(){
  let str = "";
  for(const part of this.data){
    let label = part.label;
    let urls = part.urls;
    str += `<div class="container">
              <p class="label">${label}</p>`;
    for(const i of urls){
      str += `<a class="item" href="${i.url}">${i.title}</a>`
    }
    str += `</div>`;
  }
  $(this.parent).html(str);
}

$(function(){
  var CONFIG_URL = 'https://yesiam.gitee.io/config/***.json';  // 配置文件
  $.ajax({
    type:'get',
    url:CONFIG_URL,
    dataType:'json',
    success:function(data){
      var tab = new Tab(data);
      tab.init();
    },
    error:function(xhr,err){
      console.log(err);
    }
  })
})

配置文件示例 https://yesiam.gitee.io/config/\*\*\.json*

{
  "newtab":[
    {
      "label":"与我有关",
      "urls":[
        {
            "title":"Github",
            "url":"https://github.com/yes1am"
        },
        {
            "title":"码云",
            "url":"https://gitee.com/yesiam"
        }
      ]
    },
    {
      "label":"常用网站",
      "urls":[
        {
            "title":"掘金",
            "url":"https://e.xitu.io"
        }
      ]
    }
  ]
}

4.1.4 右键菜单实现

background.js

var MarkNoteUrl = "https://yesiam.gitee.io/marknote/";
chrome.contextMenus.create({
  title: "工作笔记",
  onclick: function(){
    chrome.tabs.create({url: MarkNoteUrl});
  }
});

4.2 MarkNote项目 核心为Editor.md库

var IndexDb = function(databaseName,tableName){
    this.databaseName = databaseName || "ChromeNotes";
    this.tableName = tableName || "notes";
    this.db = null;
    this.table = null;
    this.hasData = false;  // 判断当前是否有数据
    this.id = "1";
    this.editor = null;
}

IndexDb.prototype.init = function(){
    var that = this;
    var request = window.indexedDB.open(this.databaseName,1);
    request.onsuccess = function(event){
        that.db = request.result;
        that.read();
    }
    request.onerror = function(event){
        console.log("数据库打开失败");
    }

    // 下面事情执行于:数据库首次创建版本,或者window.indexedDB.open传递的新版本(版本数值要比现在的高)
    request.onupgradeneeded = function(event) {
        that.db = event.target.result;
        that.db.onerror = function(){
            console.log("数据库打开失败");
        }
        // 创建表
        that.table = that.db.createObjectStore(that.tableName, {keyPath: 'id', autoIncrement: true});

        // 表结构 必须显式申明所有的结构
        that.table.createIndex('id', 'id', {
            unique: true    
        });
        that.table.createIndex('text', 'text');
    }
}

// 新增数据
IndexDb.prototype.add = function(data){
    var that = this;
    if(this.hasData){
        return this.edit(data);
    }
    var transaction = this.db.transaction([this.tableName], 'readwrite');  // 事务
    var objectStore = transaction.objectStore(this.tableName);
    var objectStoreRequest = objectStore.add({'id':this.id, text:data});

    objectStoreRequest.onsuccess = function (event) {
        showMsg('保存成功');
        that.hasData = true;
    };

    objectStoreRequest.onerror = function (event) {
        showMsg('保存失败');
    }
}

// 读取数据
IndexDb.prototype.read = function(){
    var that = this;
    var transaction = this.db.transaction([this.tableName], 'readwrite');
    var objectStore = transaction.objectStore(this.tableName);
    var objectStoreRequest = objectStore.get(this.id);

    objectStoreRequest.onsuccess = function (event) {
        if (objectStoreRequest.result) {
            console.log('存储数据为: ' +  objectStoreRequest.result.id + " : " + objectStoreRequest.result.text);
            that.hasData = true;
            showMsg('加载成功');

            that.createMarkdown(objectStoreRequest.result.text);
          } else {
            showMsg('暂无数据');
            that.createMarkdown("");
          }
    };

    objectStoreRequest.onerror = function (event) {
        console.log('数据读取失败');
    }
}

// 更新数据
IndexDb.prototype.edit = function(data){
    var transaction = this.db.transaction([this.tableName], 'readwrite');
    var objectStore = transaction.objectStore(this.tableName);
    var objectStoreRequest = objectStore.put({ id: this.id,text:data});

    objectStoreRequest.onsuccess = function (event) {
        showMsg('保存成功');
        // console.log('数据更新成功');
    };

    objectStoreRequest.onerror = function (event) {
        console.log('数据更新失败');
    }
}

// 删除数据
IndexDb.prototype.delete = function(){
    var transaction = this.db.transaction([this.tableName], 'readwrite');  // 事务
    var objectStore = transaction.objectStore(this.tableName);
    var objectStoreRequest = objectStore.delete(this.id);

    objectStoreRequest.onsuccess = function (event) {
        console.log('数据删除成功');
    };
}

// 生成markdown
IndexDb.prototype.createMarkdown = function(md){
    var that = this;
    this.editor = editormd("editormd", {
        path : './lib/',
        width:"90%",
        height:"720px",
        editorTheme:"mdn-like",
        toolbarIcons : function() {
            return [
                "undo", "redo", "|","watch", "preview"
            ]
        },
        saveHTMLToTextarea : true,
        appendMarkdown:md,
        onload:function(){
            var keyMap = {
                "Ctrl-S": function() {
                    var data = that.editor.getMarkdown();
                    that.add(data)
                }
            };
            that.editor.addKeyMap(keyMap);
            showMsg("初始化成功");
        }
    });
}

$(function() {
    var indexdb = new IndexDb();
    indexdb.init();
});

五. 最终效果

视频录制及制作git图软件为 ScreenToGif

六. 写在最后

目前该插件实现的效果已满足我的需求,json文件和'MarkNote'静态编辑器页面托管在码云平台,无需个人的服务器及数据库资源。
整体开发过程大多是整合了现有的资源,仅是为了打造属于自己的一个小环境,代码较为粗糙,不是最好,但适合我。
编辑器测试地址 修改完笔记记得键盘Ctrl + S保存。

雷同代码及icon,均来自以下参考博客及资源,侵删:

参考资料:

小茗同学 Chrome 插件开发攻略

张鑫旭 IndexedDB 教程

Editor.md 编辑器核心库

MarkNote Github源码

插件 Github源码

欢迎交流。

猜你喜欢

转载自www.cnblogs.com/songjp/p/9611298.html
今日推荐