Remove TinyMce Added Squire
This commit is contained in:
@@ -4,7 +4,7 @@
|
||||
id="InputNotes"
|
||||
class="master-note-edit"
|
||||
@keyup.esc="close"
|
||||
:class="[{'size-down':(sizeDown == true)}, 'position-'+position ]"
|
||||
:class="[{'size-down':(sizeDown == true), 'padded-bottom':extraToolbarsVisible }, 'position-'+position ]"
|
||||
:style="{ 'background-color':styleObject['noteBackground'], 'color':styleObject['noteText']}"
|
||||
>
|
||||
|
||||
@@ -15,64 +15,83 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<span class="note-status-indicator" v-on:click="save()">{{statusText}}</span>
|
||||
<div class="note-menu">
|
||||
|
||||
<div class="nm-button" v-on:click="close">
|
||||
<i class="close icon"></i>
|
||||
</div>
|
||||
<div class="nm-button" v-on:click="toggleList('ol')">
|
||||
<i class="list ol icon"></i>
|
||||
</div>
|
||||
<div class="nm-button" v-on:click="toggleList('ul')">
|
||||
<i class="tasks icon"></i>
|
||||
</div>
|
||||
<div class="nm-button" v-on:click="toggleBold()">
|
||||
<i class="bold icon"></i>
|
||||
</div>
|
||||
|
||||
<div class="nm-button" v-on:click="toggleItalic()">
|
||||
<i class="quote left icon"></i>
|
||||
</div>
|
||||
|
||||
<div class="nm-button" v-on:click="modifyFont('2.286em') ">
|
||||
<i class="text height icon"></i>
|
||||
</div>
|
||||
|
||||
<div v-if="usersOnNote > 1" class="nm-button">
|
||||
<i class="green user circle icon"></i>{{usersOnNote}}
|
||||
</div>
|
||||
|
||||
<div class="tinymce-container">
|
||||
<textarea :id="noteid+'-tinymce-editor'">{{noteText}}</textarea>
|
||||
</div>
|
||||
|
||||
<div id="squire-id" class="squire-box" ref="squirebox"></div>
|
||||
|
||||
<!-- && this.$store.getters.getIsUserOnMobile -->
|
||||
<span class="note-status-indicator" v-on:click="save()" v-if="statusText != 'Saved' && $store.getters.getIsUserOnMobile">
|
||||
<div class="ui green button">{{statusText}}</div>
|
||||
</span>
|
||||
|
||||
<color-picker
|
||||
v-if="colorPickerVisible"
|
||||
:location="colorPickerLocation"
|
||||
@changeColor="onChangeColor"
|
||||
:style-object="styleObject"
|
||||
@changeColor="onChangeColor"
|
||||
@close="onCloseColorChanger"
|
||||
:style-object="styleObject"
|
||||
/>
|
||||
|
||||
<div v-if="$store.getters.getIsNoteSettingsOpen">
|
||||
|
||||
<div class="all-settings">
|
||||
<div class="ui grid">
|
||||
<div class="row">
|
||||
<div class="sixteen wide column">
|
||||
<!-- Note options on the bottom of note -->
|
||||
<div class="all-settings" :class="{ 'low-settings':!extraToolbarsVisible }">
|
||||
|
||||
<note-tag-edit :noteId="noteid" :key="'tags-for-note-'+noteid"/><br>
|
||||
<div class="note-menu">
|
||||
|
||||
<!-- close button -->
|
||||
<div class="ui small compact basic icon button" v-on:click="$store.commit('toggleNoteSettingsPane')">
|
||||
<i class="close icon"></i> Close Settings
|
||||
</div>
|
||||
<!-- Pin Button -->
|
||||
<div @click="onToggleArchived" class="ui small compact basic icon button">
|
||||
<i class="archive icon" :class="{green:(archived == 1)}"></i>
|
||||
{{(archived == 1)?'Archived':'Archive'}}
|
||||
</div>
|
||||
<!-- archive button -->
|
||||
<div @click="onTogglePinned" class="ui small compact basic icon button">
|
||||
<i class="pin icon" :class="{green:(pinned == 1)}"></i>
|
||||
{{(pinned == 1)?'Pinned':'Pin'}}
|
||||
</div>
|
||||
<!-- colors button -->
|
||||
<span class="relative" v-on:click="showColorPicker">
|
||||
<span class="ui small compact basic icon button">
|
||||
<i class="paint brush icon"></i>
|
||||
Colors
|
||||
</span>
|
||||
</span>
|
||||
|
||||
<!-- attachment button -->
|
||||
<div v-if="attachmentCount > 0" class="ui small compact basic icon button" v-on:click="openEditAttachment">
|
||||
<i class="folder icon"></i> Attachments
|
||||
</div>
|
||||
<!-- file upload button -->
|
||||
<file-upload-button :noteId="noteid" />
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<!-- <note-tag-edit :noteId="noteid" :key="'tags-for-note-'+noteid"/><br> -->
|
||||
|
||||
<!-- Pin Button -->
|
||||
<div @click="onToggleArchived" class="nm-button">
|
||||
<i class="archive icon" :class="{green:(archived == 1)}"></i>
|
||||
{{(archived == 1)?'Archived':'Archive'}}
|
||||
</div>
|
||||
<!-- archive button -->
|
||||
<div @click="onTogglePinned" class="nm-button">
|
||||
<i class="pin icon" :class="{green:(pinned == 1)}"></i>
|
||||
{{(pinned == 1)?'Pinned':'Pin'}}
|
||||
</div>
|
||||
<!-- colors button -->
|
||||
<span class="nm-button" v-on:click="showColorPicker">
|
||||
<i class="paint brush icon"></i>
|
||||
Colors
|
||||
</span>
|
||||
|
||||
<!-- attachment button -->
|
||||
<div class="nm-button" v-on:click="openEditAttachment">
|
||||
<i class="folder icon"></i> Files
|
||||
</div>
|
||||
<!-- file upload button -->
|
||||
<file-upload-button class="nm-button" :noteId="noteid" />
|
||||
|
||||
</div>
|
||||
<!-- <div class="shade" v-on:click="showAllSettings = false"></div> -->
|
||||
</div>
|
||||
<!-- <div class="shade" v-on:click="showAllSettings = false"></div> -->
|
||||
|
||||
</div>
|
||||
</template>
|
||||
@@ -80,6 +99,7 @@
|
||||
<script>
|
||||
|
||||
import axios from 'axios'
|
||||
const DiffMatchPatch = require('../../../server/helpers/DiffMatchPatch')
|
||||
|
||||
export default {
|
||||
name: 'InputNotes',
|
||||
@@ -96,11 +116,13 @@
|
||||
loadingMessage: 'Loading Note',
|
||||
currentNoteId: 0,
|
||||
noteText: '',
|
||||
diffNoteText: '',
|
||||
statusText: 'Saved',
|
||||
lastNoteHash: null,
|
||||
saveDebounce: null, //Prevent save from being called numerous times quickly
|
||||
updated: 'Never',
|
||||
editDebounce: null,
|
||||
emitChangeDebounce: null,
|
||||
keyPressesCounter: 0, //Determen keys pressed between saves
|
||||
pinned: 0,
|
||||
archived: 0,
|
||||
@@ -116,6 +138,13 @@
|
||||
//Settings vars
|
||||
showAllSettings: true,
|
||||
lastVisibilityState: null,
|
||||
|
||||
//All the squire settings
|
||||
editor: null,
|
||||
// pastFocusedNode: null,
|
||||
usersOnNote: 0,
|
||||
|
||||
extraToolbarsVisible: true,
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
@@ -135,136 +164,189 @@
|
||||
}
|
||||
},
|
||||
beforeMount(){
|
||||
//Load tinymce into the page only do it once
|
||||
if(document.querySelectorAll('[data-mceload]').length == 0){
|
||||
let tinyMceIncluder = document.createElement('script')
|
||||
tinyMceIncluder.setAttribute('src', '/api/static/assets/tinymce/tinymce.min.js')
|
||||
tinyMceIncluder.setAttribute('data-mceload','loaded')
|
||||
document.head.appendChild(tinyMceIncluder)
|
||||
}
|
||||
this.$bus.$on('new_file_upload', ({noteId, imageCode}) => {
|
||||
if(this.noteid == noteId && this.editor){
|
||||
this.editor.moveCursorToEnd()
|
||||
this.editor.insertHTML(imageCode)
|
||||
}
|
||||
})
|
||||
},
|
||||
beforeDestroy(){
|
||||
|
||||
document.removeEventListener('visibilitychange', this.visibiltyChangeAction)
|
||||
this.$io.emit('leave_room', this.noteid)
|
||||
|
||||
// this.$off() // Remove all event listeners
|
||||
// this.$bus.$off()
|
||||
document.removeEventListener('visibilitychange', this.checkForUpdatedNote)
|
||||
|
||||
//Trash editor instance on close
|
||||
this.tinymce.remove()
|
||||
this.editor.destroy()
|
||||
|
||||
this.$bus.$off('new_file_upload')
|
||||
|
||||
},
|
||||
mounted: function() {
|
||||
|
||||
//Change TinyMce styles on nightmored change
|
||||
this.$bus.$on('toggle_night_mode', this.setEditorTextColor )
|
||||
|
||||
document.addEventListener('visibilitychange', this.checkForUpdatedNote)
|
||||
|
||||
this.$nextTick(() => {
|
||||
|
||||
this.loadNote(this.noteid)
|
||||
|
||||
//Tell server to push this note into a room
|
||||
this.$io.emit('join_room', this.noteid)
|
||||
|
||||
this.$io.on('update_user_count', userCount => {
|
||||
this.usersOnNote = userCount
|
||||
})
|
||||
|
||||
//Server will hand deliver diffs from other notes to this one
|
||||
this.$io.on('incoming_diff', incomingDiffData => {
|
||||
this.patchText(incomingDiffData)
|
||||
})
|
||||
|
||||
|
||||
})
|
||||
|
||||
|
||||
|
||||
},
|
||||
methods: {
|
||||
initTinyMce(){
|
||||
initSquire(){
|
||||
|
||||
//Set up squire and load note text
|
||||
this.editor = new Squire( this.$refs.squirebox, {blockTag: 'p' })
|
||||
this.setText(this.noteText)
|
||||
|
||||
// image_list: [
|
||||
// {title: 'My image 1', value: 'https://www.tinymce.com/my1.gif'},
|
||||
// {title: 'My image 2', value: 'http://www.moxiecode.com/my2.gif'}
|
||||
// ]
|
||||
//Open links when clicked in editor
|
||||
this.editor.addEventListener('click', e => {
|
||||
|
||||
//Default plugin options for big browsers
|
||||
let toolbarOptions = 'customCloseButton | mceTogglePinned | forecolor styleselect | bold italic underline | link | bullist numlist | outdent indent table | h | image'
|
||||
let pluginOptions = 'paste, link, code, lists, table, hr, image'
|
||||
//Link clicked in editor - open link
|
||||
if(e.target.nodeName == 'A' && e.target.href){
|
||||
window.open(e.target.href)
|
||||
}
|
||||
|
||||
//Tweak doc height for mobile
|
||||
let docHeight = 'calc(100vh - 1px)'
|
||||
if(this.$store.getters.getIsUserOnMobile){
|
||||
docHeight = 'calc(100vh - 1px)'
|
||||
//List Item clicked in editor - toggle link state
|
||||
if(e.target.nodeName == 'LI'){
|
||||
|
||||
toolbarOptions = 'customCloseButton | bullist numlist | mceTogglePinned'
|
||||
pluginOptions = 'lists'
|
||||
}
|
||||
let el = e.target
|
||||
|
||||
//setup skin as dark if night mode is enabled
|
||||
let skin = 'oxide'
|
||||
if(this.$store.getters.getIsNightMode){
|
||||
skin = 'oxide-dark'
|
||||
}
|
||||
//Adjust ofset by 40 px
|
||||
let correction = 40
|
||||
|
||||
const editorId = '#'+this.noteid+'-tinymce-editor'
|
||||
let vm = this
|
||||
//Determine if element was clicked or area before it, before means checkbox was clicked
|
||||
if (e.offsetX > e.target.offsetLeft - correction) {
|
||||
//Element was clicked
|
||||
} else {
|
||||
|
||||
//Globally defined included in index HTML
|
||||
tinymce.init({
|
||||
selector: editorId,
|
||||
toolbar: toolbarOptions,
|
||||
plugins: pluginOptions,
|
||||
browser_spellcheck: true,
|
||||
menubar: false,
|
||||
branding: false,
|
||||
statusbar: false,
|
||||
height: docHeight,
|
||||
skin: skin,
|
||||
contextmenu: false,
|
||||
init_instance_callback: this.editorInitCallback,
|
||||
imagetools_toolbar: "imageoptions",
|
||||
setup: editor => {
|
||||
//Add custom buttons to tinymce instance
|
||||
editor.ui.registry.addButton('customCloseButton', {
|
||||
text: 'Close',
|
||||
icon: 'close',
|
||||
onAction: function (_) {
|
||||
vm.close()
|
||||
//Will hide keyboard if clicked, much better for mobile
|
||||
this.editor.blur()
|
||||
|
||||
//Area before element was clicked, they clicked the checkbox
|
||||
this.onKeyup()
|
||||
if (el.className === 'active'){
|
||||
el.className = 'inactive';
|
||||
} else {
|
||||
el.className = 'active';
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
//Add custom buttons to tinymce instance
|
||||
editor.ui.registry.addButton('mceTogglePinned', {
|
||||
text: 'Note Settings',
|
||||
icon: 'settings',
|
||||
onAction: function (_) {
|
||||
vm.$store.commit('toggleNoteSettingsPane')
|
||||
}
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
})
|
||||
|
||||
this.editor.addEventListener('keydown', event => {
|
||||
|
||||
//Prevent new list items from having
|
||||
this.$nextTick( () => {
|
||||
//Wait a moment to get item under cursor
|
||||
let selection = this.editor.getSelection()
|
||||
let container = selection.commonAncestorContainer
|
||||
|
||||
//If user hit enter on a list, make sure the next list item isn't active
|
||||
if(container.nodeName == 'LI' && event.keyCode == 13 && container.classList){
|
||||
container.classList.remove('active')
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
//Bind event handlers
|
||||
this.editor.addEventListener('keyup', event => this.onKeyup(event) )
|
||||
|
||||
//Show and hide additional toolbars
|
||||
this.editor.addEventListener('focus', e => {
|
||||
if(this.$store.getters.getIsUserOnMobile){
|
||||
this.extraToolbarsVisible = false
|
||||
}
|
||||
})
|
||||
this.editor.addEventListener('blur', e => {
|
||||
this.save()
|
||||
this.extraToolbarsVisible = true
|
||||
})
|
||||
},
|
||||
editorInitCallback(editor){
|
||||
//If nothing is selected, select the entire line
|
||||
selectLineIfNoSelect(){
|
||||
//Select entire line if range is not set
|
||||
let selection = this.editor.getSelection()
|
||||
|
||||
this.loading = false //Turn off loading screed when editor is loaded
|
||||
this.tinymce = editor
|
||||
if(selection.startOffset == selection.endOffset && selection.startContainer == selection.endContainer){
|
||||
|
||||
this.setEditorTextColor()
|
||||
|
||||
editor
|
||||
.on('Change', this.onKeyup )
|
||||
.on('keyup', this.onKeyup )
|
||||
.on('blur', this.save )
|
||||
let squireRange = this.editor.createRange(
|
||||
selection.startContainer, 0,
|
||||
selection.endContainer, selection.commonAncestorContainer.textContent.length)
|
||||
|
||||
this.editor.setSelection(squireRange)
|
||||
}
|
||||
},
|
||||
setEditorTextColor(){
|
||||
//Only Set editor text color, background is transparent and set on parent element
|
||||
modifyFont(inSize){
|
||||
this.selectLineIfNoSelect()
|
||||
|
||||
//There may be scenarios where editor has not been set up
|
||||
if(this.tinymce){
|
||||
//Set editor color to color from app, change with night mode
|
||||
this.tinymce.getBody().style.color = getComputedStyle(document.documentElement)
|
||||
.getPropertyValue('--text_color');
|
||||
let fontInfo = this.editor.getFontInfo()
|
||||
//Toggle font size between large and normal
|
||||
if(fontInfo.size){
|
||||
this.editor.setFontSize(null)
|
||||
} else {
|
||||
this.editor.setFontSize(inSize)
|
||||
}
|
||||
},
|
||||
toggleList(type){
|
||||
|
||||
//Overwrite set color if theme is set for note.
|
||||
if(this.styleObject && this.styleObject.noteText){
|
||||
this.tinymce.getBody().style.color = this.styleObject.noteText
|
||||
}
|
||||
//Undo list if its already a lits
|
||||
if(this.editor.hasFormat(type)){
|
||||
this.editor.removeList()
|
||||
return
|
||||
}
|
||||
|
||||
if(type == 'ol'){
|
||||
this.editor.makeOrderedList()
|
||||
}
|
||||
if(type == 'ul'){
|
||||
this.editor.makeUnorderedList()
|
||||
}
|
||||
},
|
||||
toggleBold(){
|
||||
this.selectLineIfNoSelect()
|
||||
if( this.editor.hasFormat('b') ){
|
||||
this.editor.removeBold()
|
||||
} else {
|
||||
this.editor.bold()
|
||||
}
|
||||
},
|
||||
toggleItalic(){
|
||||
this.selectLineIfNoSelect()
|
||||
if( this.editor.hasFormat('i') ){
|
||||
this.editor.removeItalic()
|
||||
} else {
|
||||
this.editor.italic()
|
||||
}
|
||||
},
|
||||
setText(inText){
|
||||
return this.tinymce.setContent(inText)
|
||||
|
||||
this.editor.setHTML(inText)
|
||||
this.noteText = this.editor._getHTML()
|
||||
this.diffNoteText = this.editor._getHTML()
|
||||
},
|
||||
getText(){
|
||||
//Return text from tinyMce Editor
|
||||
return this.tinymce.getContent()
|
||||
|
||||
return this.editor.getHTML()
|
||||
},
|
||||
showColorPicker(event){
|
||||
this.colorPickerVisible = !this.colorPickerVisible
|
||||
@@ -293,13 +375,14 @@
|
||||
this.lastNoteHash = 0
|
||||
this.save()
|
||||
},
|
||||
onCloseColorChanger(){
|
||||
this.colorPickerVisible = false
|
||||
},
|
||||
onChangeColor(newStyleObject){
|
||||
|
||||
//Set new style object for note, page will use some styles, styles will be saved to database
|
||||
this.styleObject = newStyleObject
|
||||
|
||||
this.setEditorTextColor()
|
||||
|
||||
this.lastNoteHash = 0 //Update hash to force note update on next save
|
||||
this.save()
|
||||
},
|
||||
@@ -320,11 +403,15 @@
|
||||
|
||||
//Set up local data
|
||||
vm.currentNoteId = noteId
|
||||
|
||||
vm.noteText = response.data.text
|
||||
vm.diffNoteText = response.data.text
|
||||
|
||||
vm.updated = response.data.updated
|
||||
vm.lastNoteHash = vm.hashString(response.data.text)
|
||||
//Set up note colors
|
||||
if(response.data.color){
|
||||
vm.styleObject = JSON.parse(response.data.color) //Load styles json from DB
|
||||
vm.styleObject = JSON.parse(response.data.color)
|
||||
}
|
||||
|
||||
if(response.data.pinned != null){
|
||||
@@ -333,8 +420,11 @@
|
||||
vm.archived = response.data.archived
|
||||
vm.attachmentCount = response.data.attachment_count
|
||||
|
||||
this.loading = false
|
||||
|
||||
vm.$nextTick(() => {
|
||||
this.initTinyMce()
|
||||
// this.initTinyMce()
|
||||
this.initSquire()
|
||||
})
|
||||
|
||||
})
|
||||
@@ -342,9 +432,176 @@
|
||||
console.log('Could not fetch note')
|
||||
}
|
||||
},
|
||||
onKeyup(){
|
||||
diffText(){
|
||||
|
||||
this.statusText = 'Modified'
|
||||
// dont emit to one user
|
||||
if(this.usersOnNote <= 1){
|
||||
return
|
||||
}
|
||||
|
||||
//Post latest diff to server, server will emit change event to all connected clients
|
||||
// clearTimeout(this.emitChangeDebounce)
|
||||
this.emitChangeDebounce = setTimeout(i => {
|
||||
|
||||
//caldulate text diff
|
||||
let oldText = this.diffNoteText
|
||||
let newText = this.getText()
|
||||
|
||||
if(oldText == newText){
|
||||
return
|
||||
}
|
||||
|
||||
const dmp = new DiffMatchPatch.diff_match_patch()
|
||||
const diff = dmp.diff_main(oldText, newText)
|
||||
// dmp.diff_cleanupSemantic(diff)
|
||||
const patch_list = dmp.patch_make(oldText, newText, diff);
|
||||
const patch_text = dmp.patch_toText(patch_list);
|
||||
|
||||
|
||||
var patches = dmp.patch_fromText(patch_text);
|
||||
var results = dmp.patch_apply(patches, oldText);
|
||||
|
||||
const computedText = results[0]
|
||||
|
||||
//Save computed diff text
|
||||
this.noteText = computedText
|
||||
this.diffNoteText = computedText
|
||||
|
||||
if(patch_text == ''){
|
||||
return
|
||||
}
|
||||
|
||||
// console.log(patch_text)
|
||||
this.$io.emit('note_diff', {
|
||||
id:this.currentNoteId,
|
||||
diff:patch_text
|
||||
})
|
||||
|
||||
|
||||
}, 5)
|
||||
},
|
||||
patchText(patch_text){
|
||||
|
||||
console.log(patch_text)
|
||||
|
||||
//
|
||||
// Capture x,y of caret and position into string
|
||||
//
|
||||
|
||||
let currentSelection = this.editor.getSelection()
|
||||
let lineText = currentSelection.startContainer.textContent
|
||||
console.log(lineText)
|
||||
let cursorOffset = parseInt(currentSelection.startOffset) //number of characters in
|
||||
let path = this.xpath(currentSelection.commonAncestorContainer.parentElement)
|
||||
console.log(path)
|
||||
|
||||
|
||||
//
|
||||
//Set up text to process diff
|
||||
//
|
||||
|
||||
let currentText = this.editor._getHTML()
|
||||
const startingLines = (currentText.match(/<br>/g) || '').length + 1
|
||||
console.log('1')
|
||||
|
||||
const dmp = new DiffMatchPatch.diff_match_patch()
|
||||
var patches = dmp.patch_fromText(patch_text);
|
||||
var results = dmp.patch_apply(patches, currentText);
|
||||
let newText = results[0]
|
||||
console.log('2')
|
||||
|
||||
this.noteText = newText
|
||||
this.diffNoteText = newText
|
||||
console.log('3')
|
||||
// this.editor._setHTML(newText)
|
||||
this.editor.setHTML(newText)
|
||||
|
||||
console.log('4')
|
||||
|
||||
//
|
||||
// I user hasn't selected the document, we are done here
|
||||
// @TODO add code to halt execution
|
||||
//
|
||||
|
||||
const endingLines = (newText.match(/<br>/g) || '').length + 1
|
||||
|
||||
// if(this.pastFocusedNode != null || true){
|
||||
setTimeout( ()=>{
|
||||
|
||||
var root = this.editor.getRoot()
|
||||
//Get node under current x,y on dom (may break on scroll)
|
||||
// let node = document.elementFromPoint(mouse.x, mouse.y)
|
||||
let node = this.getElementByXPath(path)
|
||||
|
||||
if(node.firstChild){
|
||||
node = node.firstChild
|
||||
}
|
||||
|
||||
//If the number of lines changed
|
||||
if(startingLines != endingLines){
|
||||
|
||||
//Line diff may be +1 or -1
|
||||
let lineDiff = endingLines - startingLines
|
||||
console.log('Line Diff => ', lineDiff)
|
||||
|
||||
//Pull out node number from path
|
||||
var nodeNumber = path.match(/\d+/)
|
||||
let modifyNode = null
|
||||
if(nodeNumber.length == 1){
|
||||
modifyNode = parseInt(nodeNumber[0])
|
||||
}
|
||||
|
||||
path = path.replace(modifyNode, modifyNode + lineDiff )
|
||||
console.log(path)
|
||||
let maybeNext = this.getElementByXPath(path)
|
||||
if(maybeNext && maybeNext.firstChild){
|
||||
maybeNext = maybeNext.firstChild
|
||||
}
|
||||
|
||||
if(maybeNext && maybeNext.textContent == lineText){
|
||||
node = maybeNext
|
||||
console.log('The Node Moved!')
|
||||
}
|
||||
}
|
||||
|
||||
console.log('Targeting Node')
|
||||
console.log(node)
|
||||
|
||||
//Create and set range
|
||||
let squireRange = this.editor.createRange(node, cursorOffset)
|
||||
squireRange.collapse(true)
|
||||
this.editor.setSelection(squireRange)
|
||||
console.log('cursor set')
|
||||
|
||||
}, 20)
|
||||
// }
|
||||
|
||||
|
||||
|
||||
},
|
||||
xpath(el) {
|
||||
//Skip things we can't use
|
||||
if (typeof el == "string") return document.evaluate(el, document, null, 0, null)
|
||||
if (!el || el.nodeType != 1) return ''
|
||||
|
||||
//Anchor xpath using Ids or test-ids
|
||||
const testId = el.getAttribute('test-id')
|
||||
if (el.id) return "//*[@id='" + el.id + "']"
|
||||
|
||||
//Continue to build path
|
||||
const sames = [].filter.call(el.parentNode.children, function (x) { return x.tagName == el.tagName })
|
||||
return this.xpath(el.parentNode) + '/' + el.tagName.toLowerCase() + (sames.length > 1 ? '['+([].indexOf.call(sames, el)+1)+']' : '')
|
||||
},
|
||||
getElementByXPath(xpath) {
|
||||
return new XPathEvaluator()
|
||||
.createExpression(xpath)
|
||||
.evaluate(document, XPathResult.FIRST_ORDERED_NODE_TYPE) .singleNodeValue
|
||||
},
|
||||
onKeyup(event){
|
||||
|
||||
this.statusText = 'Save'
|
||||
|
||||
this.diffText()
|
||||
|
||||
//Each note, save after 5 seconds, focus lost or 30 characters typed.
|
||||
clearTimeout(this.editDebounce)
|
||||
@@ -364,6 +621,8 @@
|
||||
//Clear other debounced events to prevent double calling of save
|
||||
// clearTimeout(this.editDebounce)
|
||||
|
||||
// return resolve(true)
|
||||
|
||||
//Don't save note if its hash doesn't change
|
||||
const currentNoteText = this.getText()
|
||||
if( this.lastNoteHash == this.hashString( currentNoteText )){
|
||||
@@ -406,9 +665,12 @@
|
||||
},
|
||||
checkForUpdatedNote(){
|
||||
|
||||
// return
|
||||
|
||||
//If user leaves page then returns to page, reload the first batch
|
||||
if(this.lastVisibilityState == 'hidden' && document.visibilityState == 'visible'){
|
||||
console.log('Checking for changes is note data')
|
||||
console.log('Checking for note updates after visibility change.')
|
||||
|
||||
const postData = {
|
||||
noteId:this.currentNoteId,
|
||||
text:this.getText(),
|
||||
@@ -435,12 +697,12 @@
|
||||
hashString(text){
|
||||
|
||||
var hash = 0;
|
||||
if (text.length == 0) {
|
||||
if (text == null || text.length == 0) {
|
||||
return hash;
|
||||
}
|
||||
|
||||
//Simplified for speed
|
||||
return text.length
|
||||
// return text.length
|
||||
|
||||
for (let i = 0; i < text.length; i++) {
|
||||
let char = text.charCodeAt(i);
|
||||
@@ -472,42 +734,67 @@
|
||||
|
||||
<style type="text/css" scoped>
|
||||
|
||||
/* squire note menu button */
|
||||
|
||||
.note-menu {
|
||||
width: 100%;
|
||||
display: block;
|
||||
background: #221f2b;
|
||||
color: white;
|
||||
overflow: hidden;
|
||||
border: 1px solid #534c68;
|
||||
}
|
||||
.note-menu > .nm-button {
|
||||
padding: 10px 10px;
|
||||
cursor: pointer;
|
||||
text-align: center;
|
||||
box-sizing: border-box;
|
||||
font-size: 1.1em;
|
||||
vertical-align: middle;
|
||||
/*height: 40px;*/
|
||||
display: table-cell;
|
||||
}
|
||||
.nm-button > i {
|
||||
font-size: 1.1em;
|
||||
margin: 0;
|
||||
}
|
||||
.nm-button:hover {
|
||||
background-color: #534c68;
|
||||
color: white;
|
||||
}
|
||||
.nm-button + .nm-button {
|
||||
border-left: 1px solid #534c68;
|
||||
}
|
||||
|
||||
/* squire styles */
|
||||
|
||||
/*Settings manager styles */
|
||||
.all-settings {
|
||||
/*border-top: 1px solid #534c68;*/
|
||||
background: #221f2b;
|
||||
position: absolute;
|
||||
bottom: -5px;
|
||||
right: 10px;
|
||||
left: 10px;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
left: 0;
|
||||
z-index: 99;
|
||||
border: 1px solid;
|
||||
background-color: var(--background_color);
|
||||
border-color: var(--border_color);
|
||||
/*border: 1px solid;*/
|
||||
/*background-color: var(--background_color);*/
|
||||
/*border-color: var(--border_color);*/
|
||||
box-sizing: border-box;
|
||||
border-radius: 7px;
|
||||
box-shadow: 0px 3px 7px 0px rgba(140,140,140,1);
|
||||
padding: 1em;
|
||||
/*border-radius: 7px;*/
|
||||
/*box-shadow: 0px 3px 7px 0px rgba(140,140,140,1);*/
|
||||
/*padding: 1.2em 0 0;*/
|
||||
}
|
||||
.low-settings {
|
||||
bottom: 0px;
|
||||
cursor: pointer;
|
||||
height: 1.4em;
|
||||
padding-top: 1.5em;
|
||||
overflow: hidden;
|
||||
border: 1px solid #534c68;
|
||||
}
|
||||
/*End Settings manager styles */
|
||||
|
||||
.tinymce-container {
|
||||
/* Uncomment this to see the */
|
||||
/*border-bottom: 2px solid green !important;*/
|
||||
}
|
||||
|
||||
.note-top-menu {
|
||||
width: 100%;
|
||||
display: inline-block;
|
||||
height: 37px;
|
||||
border-left: 3px solid var(--border_color);
|
||||
}
|
||||
.note-top-menu .ui.basic.button {
|
||||
border-radius: 0;
|
||||
border: none;
|
||||
border-right: 1px solid var(--border_color);
|
||||
margin: 0px -2px;
|
||||
padding-left: 15px;
|
||||
padding-right: 15px;
|
||||
}
|
||||
|
||||
/* container styles change based on mobile and number of open screens */
|
||||
.master-note-edit {
|
||||
@@ -520,6 +807,9 @@
|
||||
z-index: 1001;
|
||||
/*overflow-x: scroll;*/
|
||||
}
|
||||
.padded-bottom {
|
||||
padding-bottom: 20px;
|
||||
}
|
||||
.loading-note {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
|
Reference in New Issue
Block a user