2
0
mirror of https://github.com/tenrok/vue-tribute.git synced 2026-06-23 06:30:35 +03:00

Initial commit

This commit is contained in:
syropian
2016-07-24 11:08:04 -04:00
parent 0f41d8985e
commit 7df4c3dbed
9 changed files with 193 additions and 201 deletions
+3
View File
@@ -0,0 +1,3 @@
{
"presets": [ "es2015-rollup" ]
}
+4 -4
View File
@@ -1,11 +1,11 @@
# vue-prosemirror # vue-input-autosize
> A simple Vue.js wrapper around the ProseMirror editor > A simple Vue.js directive for autosizing a text input based on its content.
## Install ## Install
```js ```js
$ npm install vue-prosemirror --save $ npm install vue-input-autosize --save
``` ```
## Usage ## Usage
@@ -19,4 +19,4 @@ Coming soon...
## TODO ## TODO
- [ ] Tests - [ ] Tests
- [ ] Tidy up example - [ ] Improve the example
+9 -28
View File
@@ -1,40 +1,21 @@
<template> <template>
<textarea @keyup="syncToEditor">{{ editorDisplayVal }}</textarea> <input type="text" v-input-autosize v-model="foo" placeholder="Butts" />
<prosemirror :content="editorVal" :on-change="editorChanged" menu-type="tooltip"></prosemirror>
</template> </template>
<script> <script>
import VueProseMirror from "../"; import Vue from "vue";
import VueInputAutosize from "../";
Vue.use(VueInputAutosize);
export default { export default {
name: "app", name: "app",
data(){
return {
editorVal: "",
editorDisplayVal: ""
}
},
ready(){ ready(){
console.log("Ready!") console.log("Ready!")
}, },
methods: { data(){
editorChanged(raw, rendered){ return {
this.editorDisplayVal = raw; foo: "Hello"
console.log(rendered)
},
syncToEditor($event){
this.editorVal = $event.target.value;
} }
},
components: {
prosemirror: VueProseMirror
} }
} }
</script> </script>
<style>
.vueProseMirror .ProseMirror .ProseMirror-content{
width: 500px;
margin: 50px auto;
border: 1px solid #eee;
outline: none;
padding: 10px;
}
</style>
+47 -73
View File
@@ -1,81 +1,55 @@
'use strict'; 'use strict';
function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; } exports.install = function (Vue, options) {
Vue.directive("input-autosize", {
mirror: null,
val: " ",
options: {},
bind: function bind() {
var _this = this;
var prosemirror = _interopDefault(require('prosemirror')); var defaults = { maxWidth: 500, minWidth: 20, comfortZone: 0 };
var prosemirror_dist_schemaBasic = require('prosemirror/dist/schema-basic'); this.options = Object.assign(defaults, options || {});
var prosemirror_dist_markdown = require('prosemirror/dist/markdown');
var prosemirror_dist_exampleSetup = require('prosemirror/dist/example-setup');
var prosemirror_dist_menu = require('prosemirror/dist/menu');
var index = { template: "<div class=vueProseMirror></div>", this.mirror = document.createElement("span");
name: "ProseMirror", this.mirror.classList.add("vue-input-autosize-mirror");
props: { document.body.appendChild(this.mirror);
content: String,
onChange: Function, this.el.addEventListener("input", this.check.bind(this, this.el), false);
menuType: { setTimeout(function () {
type: String, var styles = window.getComputedStyle(_this.el, null);
default: "bar" Object.assign(_this.mirror.style, {
position: "absolute",
top: "-9999px",
left: "-9999px",
width: "auto",
whiteSpace: "nowrap",
fontSize: styles.getPropertyValue("font-size"),
fontFamily: styles.getPropertyValue("font-family"),
fontWeight: styles.getPropertyValue("font-weight"),
letterSpacing: styles.getPropertyValue("letter-spacing"),
textTransform: styles.getPropertyValue("text-transform"),
ariaHidden: true
});
_this.check(_this.el);
}, 0);
}, },
options: Object update: function update() {
}, this.check(this.el);
data: function data() {
return {
editor: null
};
},
computed: {
rawMarkdown: function rawMarkdown() {
return prosemirror_dist_markdown.defaultMarkdownSerializer.serialize(this.editor.doc);
}, },
renderedContent: function renderedContent() { check: function check(el) {
var docFrag = this.editor.doc.content.toDOM(); this.val = el.value;
var div = document.createElement("div"); if (!this.val) this.val = el.placeholder || "";
div.appendChild(docFrag.cloneNode(true)); this.mirror.innerHTML = this.val.replace(/&/g, "&amp;").replace(/\s/g, "&nbsp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
return div.innerHTML; var newWidth = this.mirror.getBoundingClientRect().width + this.options.comfortZone;
} if (newWidth > this.options.maxWidth) {
}, newWidth = this.options.maxWidth;
ready: function ready() { } else if (newWidth < this.options.minWidth) {
var _this = this; newWidth = this.options.minWidth;
var editorOptions = Object.assign({
schema: prosemirror_dist_schemaBasic.schema,
place: this.el,
doc: prosemirror_dist_markdown.defaultMarkdownParser.parse(this.content),
plugins: [prosemirror_dist_exampleSetup.exampleSetup.config({ menuBar: false, tooltipMenu: false })]
}, this.options);
if (editorOptions.doc === undefined || editorOptions.doc === null) {
editorOptions.doc = null;
editorOptions.docFormat = null;
}
this.editor = new prosemirror.ProseMirror(editorOptions);
var menu = prosemirror_dist_exampleSetup.buildMenuItems(prosemirror_dist_schemaBasic.schema);
if (this.menuType === "bar") {
prosemirror_dist_menu.tooltipMenu.detach(this.editor);
prosemirror_dist_menu.menuBar.config({ float: true, content: menu.fullMenu }).attach(this.editor);
} else {
prosemirror_dist_menu.menuBar.detach(this.editor);
prosemirror_dist_menu.tooltipMenu.config({
selectedBlockMenu: true,
inlineContent: menu.inlineMenu,
blockContent: menu.blockMenu
}).attach(this.editor);
}
this.editor.on.change.add(function () {
if (_this.onChange && typeof _this.onChange === "function") {
_this.onChange.apply(null, [_this.rawMarkdown, _this.renderedContent]);
} }
}); if (newWidth != el.getBoundingClientRect().width) {
el.style.width = newWidth + "px";
this.$watch("content", function (val) { }
_this.editor.setDoc(prosemirror_dist_markdown.defaultMarkdownParser.parse(val)); }
}); });
}
}; };
module.exports = index;
+61
View File
@@ -0,0 +1,61 @@
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory() :
typeof define === 'function' && define.amd ? define(factory) :
(factory());
}(this, function () { 'use strict';
exports.install = function (Vue, options) {
Vue.directive("input-autosize", {
mirror: null,
val: " ",
options: {},
bind: function bind() {
var _this = this;
var defaults = { maxWidth: 500, minWidth: 20, comfortZone: 0 };
this.options = Object.assign(defaults, options || {});
this.mirror = document.createElement("span");
this.mirror.classList.add("vue-input-autosize-mirror");
document.body.appendChild(this.mirror);
this.el.addEventListener("input", this.check.bind(this, this.el), false);
setTimeout(function () {
var styles = window.getComputedStyle(_this.el, null);
Object.assign(_this.mirror.style, {
position: "absolute",
top: "-9999px",
left: "-9999px",
width: "auto",
whiteSpace: "nowrap",
fontSize: styles.getPropertyValue("font-size"),
fontFamily: styles.getPropertyValue("font-family"),
fontWeight: styles.getPropertyValue("font-weight"),
letterSpacing: styles.getPropertyValue("letter-spacing"),
textTransform: styles.getPropertyValue("text-transform"),
ariaHidden: true
});
_this.check(_this.el);
}, 0);
},
update: function update() {
this.check(this.el);
},
check: function check(el) {
this.val = el.value;
if (!this.val) this.val = el.placeholder || "";
this.mirror.innerHTML = this.val.replace(/&/g, "&amp;").replace(/\s/g, "&nbsp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
var newWidth = this.mirror.getBoundingClientRect().width + this.options.comfortZone;
if (newWidth > this.options.maxWidth) {
newWidth = this.options.maxWidth;
} else if (newWidth < this.options.minWidth) {
newWidth = this.options.minWidth;
}
if (newWidth != el.getBoundingClientRect().width) {
el.style.width = newWidth + "px";
}
}
});
};
}));
+13 -13
View File
@@ -1,9 +1,9 @@
{ {
"name": "vue-prosemirror", "name": "vue-input-autosize",
"version": "0.1.2", "version": "0.1.0",
"description": "A simple Vue.js wrapper around the ProseMirror editor", "description": "A simple Vue.js directive to autosize text input fields",
"license": "MIT", "license": "MIT",
"repository": "syropian/vue-prosemirror", "repository": "syropian/vue-input-autosize",
"author": { "author": {
"name": "Collin Henderson", "name": "Collin Henderson",
"email": "collin@syropia.net", "email": "collin@syropia.net",
@@ -13,9 +13,11 @@
"node": ">=4" "node": ">=4"
}, },
"scripts": { "scripts": {
"build:all": "npm run build && npm run build:umd",
"build": "BUILD_ENV=cjs rollup -c", "build": "BUILD_ENV=cjs rollup -c",
"build:umd": "BUILD_ENV=umd rollup -c",
"example": "vbuild --dev -e example", "example": "vbuild --dev -e example",
"example:build": "vbuild -e example -t VueProsemirror" "example:build": "vbuild -e example -t VueInputAutosize"
}, },
"main": "index.js", "main": "index.js",
"files": [ "files": [
@@ -23,18 +25,16 @@
"index.umd.js" "index.umd.js"
], ],
"keywords": [ "keywords": [
"prosemirror", "autosize",
"editor", "autogrow",
"markdown", "autoshrink",
"input",
"Vue" "Vue"
], ],
"dependencies": { "dependencies": {},
"prosemirror": "^0.8.3"
},
"devDependencies": { "devDependencies": {
"babel-preset-es2015-rollup": "^1.1.1", "babel-preset-es2015-rollup": "^1.1.1",
"rollup": "^0.33.0", "rollup": "^0.33.0",
"rollup-plugin-babel": "^2.6.1", "rollup-plugin-babel": "^2.6.1"
"rollup-plugin-vue": "^2.0.1"
} }
} }
+6 -5
View File
@@ -1,16 +1,17 @@
import { rollup } from "rollup" import { rollup } from "rollup"
import babel from "rollup-plugin-babel" import babel from "rollup-plugin-babel"
import vue from "rollup-plugin-vue";
const env = process.env.BUILD_ENV const env = process.env.BUILD_ENV
const dest = env === "cjs" ? "index.js" : "index.umd.js" const dest = env === "cjs" ? "index.js" : "index.umd.js"
export default { export default {
entry: "./src/index.vue", entry: "./src/index.js",
dest,
plugins: [ plugins: [
vue() babel({
exclude: "node_modules/**"
})
], ],
dest,
format: env, format: env,
moduleName: "VueProseMirror" moduleName: "VueInputAutosize"
} }
+49
View File
@@ -0,0 +1,49 @@
"use strict";
exports.install = function(Vue, options){
Vue.directive("input-autosize", {
mirror: null,
val: " ",
options: {},
bind(){
const defaults = { maxWidth: 500, minWidth: 20, comfortZone: 0 };
this.options = Object.assign(defaults, options || {});
this.mirror = document.createElement("span");
this.mirror.classList.add("vue-input-autosize-mirror");
document.body.appendChild(this.mirror);
this.el.addEventListener("input", this.check.bind(this, this.el), false);
setTimeout(() => {
let styles = window.getComputedStyle(this.el, null);
Object.assign(this.mirror.style, {
position: "absolute",
top: "-9999px",
left: "-9999px",
width: "auto",
whiteSpace: "nowrap",
fontSize: styles.getPropertyValue("font-size"),
fontFamily: styles.getPropertyValue("font-family"),
fontWeight: styles.getPropertyValue("font-weight"),
letterSpacing: styles.getPropertyValue("letter-spacing"),
textTransform: styles.getPropertyValue("text-transform"),
ariaHidden: true
});
this.check(this.el);
}, 0)
},
update(){
this.check(this.el);
},
check(el){
this.val = el.value;
if (!this.val) this.val = el.placeholder || "";
this.mirror.innerHTML = this.val.replace(/&/g, "&amp;").replace(/\s/g, "&nbsp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
let newWidth = this.mirror.getBoundingClientRect().width + this.options.comfortZone;
if( newWidth > this.options.maxWidth ){ newWidth = this.options.maxWidth; }
else if (newWidth < this.options.minWidth){ newWidth = this.options.minWidth; }
if( newWidth != el.getBoundingClientRect().width ){ el.style.width = `${newWidth}px`; }
}
});
}
-77
View File
@@ -1,77 +0,0 @@
<template>
<div class="vueProseMirror"></div>
</template>
<script>
import prosemirror from "prosemirror";
import { schema } from "prosemirror/dist/schema-basic";
import { defaultMarkdownParser, defaultMarkdownSerializer } from "prosemirror/dist/markdown";
import { exampleSetup, buildMenuItems } from "prosemirror/dist/example-setup";
import { tooltipMenu, menuBar } from "prosemirror/dist/menu";
export default {
name: "ProseMirror",
props: {
content: String,
onChange: Function,
menuType: {
type: String,
default: "bar"
},
options: Object
},
data(){
return {
editor: null
}
},
computed: {
rawMarkdown(){
return defaultMarkdownSerializer.serialize(this.editor.doc)
},
renderedContent(){
let docFrag = this.editor.doc.content.toDOM();
let div = document.createElement("div");
div.appendChild( docFrag.cloneNode(true) );
return div.innerHTML;
}
},
ready(){
const editorOptions = Object.assign({
schema,
place: this.el,
doc: defaultMarkdownParser.parse(this.content),
plugins: [exampleSetup.config({menuBar: false, tooltipMenu: false})]
}, this.options);
if (editorOptions.doc === undefined || editorOptions.doc === null) {
editorOptions.doc = null;
editorOptions.docFormat = null;
}
this.editor = new prosemirror.ProseMirror(editorOptions);
let menu = buildMenuItems(schema);
if (this.menuType === "bar") {
tooltipMenu.detach(this.editor);
menuBar.config({float: true, content: menu.fullMenu}).attach(this.editor);
}
else {
menuBar.detach(this.editor);
tooltipMenu.config({
selectedBlockMenu: true,
inlineContent: menu.inlineMenu,
blockContent: menu.blockMenu
}).attach(this.editor);
}
this.editor.on.change.add( () => {
if( this.onChange && typeof this.onChange === "function" ){
this.onChange.apply(null, [this.rawMarkdown, this.renderedContent])
}
});
this.$watch("content", (val) => {
this.editor.setDoc(defaultMarkdownParser.parse(val));
});
}
}
</script>