aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFawn <fangrui_tong@brown.edu>2019-11-14 23:01:49 -0500
committerFawn <fangrui_tong@brown.edu>2019-11-14 23:01:49 -0500
commite3f06e390f98cc5b97d63fc287daff994d5fef6f (patch)
tree9daa1a3cdbc63f2bbf0e77c5e9f8c4ec2415f3b2
parent0f72e2acc66698247503246887a5f5bb572b2753 (diff)
double cliking dragger collapses menu
-rw-r--r--src/client/util/RichTextSchema.tsx1
-rw-r--r--src/client/util/TooltipTextMenu.scss399
-rw-r--r--src/client/util/TooltipTextMenu.tsx610
3 files changed, 278 insertions, 732 deletions
diff --git a/src/client/util/RichTextSchema.tsx b/src/client/util/RichTextSchema.tsx
index 1eea529d2..69f9a4c53 100644
--- a/src/client/util/RichTextSchema.tsx
+++ b/src/client/util/RichTextSchema.tsx
@@ -130,6 +130,7 @@ export const nodes: { [index: string]: NodeSpec } = {
// }
// }]
},
+
// :: NodeSpec An inline image (`<img>`) node. Supports `src`,
// `alt`, and `href` attributes. The latter two default to the empty
// string.
diff --git a/src/client/util/TooltipTextMenu.scss b/src/client/util/TooltipTextMenu.scss
index 1f619b4f5..8310a0da6 100644
--- a/src/client/util/TooltipTextMenu.scss
+++ b/src/client/util/TooltipTextMenu.scss
@@ -1,6 +1,5 @@
@import "../views/globalCssVariables";
.ProseMirror-menu-dropdown-wrap {
- // margin: 0 4px;
display: inline-block;
position: relative;
}
@@ -39,9 +38,10 @@
font-size: 12px;
background: white;
border: 1px solid rgb(223, 223, 223);
- min-width: 50px;
+ min-width: 40px;
z-index: 50000;
position: absolute;
+ box-sizing: content-box;
.ProseMirror-menu-dropdown-item {
cursor: pointer;
@@ -91,20 +91,22 @@
.wrapper {
position: absolute;
pointer-events: all;
-}
+ display: flex;
+ align-items: center;
+ transform: translateY(-85px);
-.tooltipMenu {
- position: absolute;
- z-index: 20000;
+ height: 35px;
background: #323232;
border-radius: 6px;
- transform: translateY(-85px);
+ box-shadow: 3px 3px 3px rgba(0, 0, 0, 0.25);
+
+}
+
+.tooltipMenu, .basic-tools {
+ z-index: 20000;
pointer-events: all;
- height: 35px;
- // width: 650px;
padding: 3px;
padding-bottom: 5px;
- box-shadow: 3px 3px 3px rgba(0, 0, 0, 0.25);
display: flex;
align-items: center;
@@ -203,7 +205,7 @@
}
.underline svg {
- margin-top: 15px;
+ margin-top: 13px;
}
.font-size-indicator {
@@ -232,21 +234,19 @@
width: 1em;
height: 1em;
stroke-width: 3;
- // stroke: greenyellow;
fill: greenyellow;
margin-right: 15px;
}
-.dragger {
+.dragger-wrapper {
color: #eee;
- margin-left: 5px;
- width: 16px;
height: 22px;
- display: inline-block;
+ padding: 0 5px;
+ box-sizing: content-box;
cursor: grab;
- .dragger-wrapper {
- width: 100%;
+ .dragger {
+ width: 18px;
height: 100%;
display: flex;
justify-content: space-evenly;
@@ -259,11 +259,6 @@
}
}
-// .menuicon:hover + .ProseMirror-menu-dropdown-wrap .buttonSettings-dropdown,
-// .menuicon-active:hover + .ProseMirror-menu-dropdown-wrap .buttonSettings-dropdown {
-// background-color: black;
-// }
-
.button-dropdown-wrapper {
display: flex;
align-content: center;
@@ -374,360 +369,4 @@ button.colorPicker {
&.active {
border: 2px solid white !important;
}
-}
-
-// @import "../views/globalCssVariables";
-
-// .ProseMirror-textblock-dropdown {
-// min-width: 3em;
-// }
-
-// .ProseMirror-menu {
-// margin: 0 -4px;
-// line-height: 1;
-// }
-
-// .ProseMirror-tooltip .ProseMirror-menu {
-// width: -webkit-fit-content;
-// width: fit-content;
-// white-space: pre;
-// }
-
-// .ProseMirror-menuitem {
-// margin-right: 3px;
-// display: inline-block;
-// z-index: 50000;
-// position: relative;
-// }
-
-// .ProseMirror-menuseparator {
-// // border-right: 1px solid #ddd;
-// margin-right: 3px;
-// }
-
-// .ProseMirror-menu-dropdown, .ProseMirror-menu-dropdown-menu {
-// font-size: 90%;
-// white-space: nowrap;
-// }
-
-// .ProseMirror-menu-dropdown {
-// vertical-align: 1px;
-// cursor: pointer;
-// position: relative;
-// padding-right: 15px;
-// margin: 3px;
-// background: white;
-// border-radius: 3px;
-// text-align: center;
-// }
-
-// .ProseMirror-menu-dropdown-wrap {
-// padding: 1px 0 1px 4px;
-// display: inline-block;
-// position: relative;
-// }
-
-// .ProseMirror-menu-dropdown:after {
-// content: "";
-// border-left: 4px solid transparent;
-// border-right: 4px solid transparent;
-// border-top: 4px solid currentColor;
-// opacity: .6;
-// position: absolute;
-// right: 4px;
-// top: calc(50% - 2px);
-// }
-
-// .ProseMirror-menu-dropdown-menu, .ProseMirror-menu-submenu {
-// background: $dark-color;
-// color:white;
-// border: 1px solid rgb(223, 223, 223);
-// padding: 2px;
-// }
-
-// .ProseMirror-menu-dropdown-menu {
-// z-index: 50000;
-// min-width: 6em;
-// background: white;
-// position: absolute;
-// }
-
-// .linking {
-// text-align: center;
-// }
-
-// .ProseMirror-menu-dropdown-item {
-// cursor: pointer;
-// padding: 2px 8px 2px 4px;
-// width: auto;
-// z-index: 100000;
-// }
-
-// .ProseMirror-menu-dropdown-item:hover {
-// background: white;
-// }
-
-// .ProseMirror-menu-submenu-wrap {
-// position: relative;
-// margin-right: -4px;
-// }
-
-// .ProseMirror-menu-submenu-label:after {
-// content: "";
-// border-top: 4px solid transparent;
-// border-bottom: 4px solid transparent;
-// border-left: 4px solid currentColor;
-// opacity: .6;
-// position: absolute;
-// right: 4px;
-// top: calc(50% - 4px);
-// }
-
-// .ProseMirror-menu-submenu {
-// display: none;
-// min-width: 4em;
-// left: 100%;
-// top: -3px;
-// }
-
-// .ProseMirror-menu-active {
-// background: #eee;
-// border-radius: 4px;
-// }
-
-// .ProseMirror-menu-active {
-// background: #eee;
-// border-radius: 4px;
-// }
-
-// .ProseMirror-menu-disabled {
-// opacity: .3;
-// }
-
-// .ProseMirror-menu-submenu-wrap:hover .ProseMirror-menu-submenu, .ProseMirror-menu-submenu-wrap-active .ProseMirror-menu-submenu {
-// display: block;
-// }
-
-// .ProseMirror-menubar {
-// border-top-left-radius: inherit;
-// border-top-right-radius: inherit;
-// position: relative;
-// min-height: 1em;
-// color: white;
-// padding: 10px 10px;
-// top: 0; left: 0; right: 0;
-// border-bottom: 1px solid silver;
-// background:$dark-color;
-// z-index: 10;
-// -moz-box-sizing: border-box;
-// box-sizing: border-box;
-// overflow: visible;
-// }
-
-// .ProseMirror-icon {
-// display: inline-block;
-// line-height: .8;
-// vertical-align: -2px; /* Compensate for padding */
-// padding: 2px 8px;
-// cursor: pointer;
-// }
-
-// .ProseMirror-menu-disabled.ProseMirror-icon {
-// cursor: default;
-// }
-
-// .ProseMirror-icon svg {
-// fill:white;
-// height: 1em;
-// }
-
-// .ProseMirror-icon span {
-// vertical-align: text-top;
-// }
-
-// .ProseMirror ul, .ProseMirror ol {
-// padding-left: 30px;
-// }
-
-// .ProseMirror blockquote {
-// padding-left: 1em;
-// border-left: 3px solid #eee;
-// margin-left: 0; margin-right: 0;
-// }
-
-// .ProseMirror-example-setup-style img {
-// cursor: default;
-// }
-
-// .ProseMirror-prompt {
-// background: white;
-// padding: 5px 10px 5px 15px;
-// border: 1px solid silver;
-// position: fixed;
-// border-radius: 3px;
-// z-index: 11;
-// box-shadow: -.5px 2px 5px white(255, 255, 255, 0.2);
-// }
-
-// .ProseMirror-prompt h5 {
-// margin: 0;
-// font-weight: normal;
-// font-size: 100%;
-// color: #444;
-// }
-
-// .ProseMirror-prompt input[type="text"],
-// .ProseMirror-prompt textarea {
-// background: white;
-// border: none;
-// outline: none;
-// }
-
-// .ProseMirror-prompt input[type="text"] {
-// padding: 0 4px;
-// }
-
-// .ProseMirror-prompt-close {
-// position: absolute;
-// left: 2px; top: 1px;
-// color: #666;
-// border: none; background: transparent; padding: 0;
-// }
-
-// .ProseMirror-prompt-close:after {
-// content: "✕";
-// font-size: 12px;
-// }
-
-// .ProseMirror-invalid {
-// background: #ffc;
-// border: 1px solid #cc7;
-// border-radius: 4px;
-// padding: 5px 10px;
-// position: absolute;
-// min-width: 10em;
-// }
-
-// .ProseMirror-prompt-buttons {
-// margin-top: 5px;
-// display: none;
-// }
-
-// .tooltipMenu {
-// position: absolute;
-// z-index: 20000;
-// background: #121721;
-// border: 1px solid silver;
-// border-radius: 15px;
-// //height: 60px;
-// //padding: 2px 10px;
-// //margin-top: 100px;
-// //-webkit-transform: translateX(-50%);
-// //transform: translateX(-50%);
-// transform: translateY(-85px);
-// pointer-events: all;
-// height: fit-content;
-// width:550px;
-// .ProseMirror-example-setup-style hr {
-// padding: 2px 10px;
-// border: none;
-// margin: 1em 0;
-// }
-
-// .ProseMirror-example-setup-style hr:after {
-// content: "";
-// display: block;
-// height: 1px;
-// background-color: silver;
-// line-height: 2px;
-// }
-// }
-
-// .tooltipExtras {
-// position: absolute;
-// z-index: 20000;
-// background: #121721;
-// border: 1px solid silver;
-// border-radius: 15px;
-// //height: 60px;
-// //padding: 2px 10px;
-// //margin-top: 100px;
-// //-webkit-transform: translateX(-50%);
-// //transform: translateX(-50%);
-// transform: translateY(-115px);
-// pointer-events: all;
-// height: 25px;
-// width:fit-content;
-// .ProseMirror-example-setup-style hr {
-// padding: 2px 10px;
-// border: none;
-// margin: 1em 0;
-// }
-
-// .ProseMirror-example-setup-style hr:after {
-// content: "";
-// display: block;
-// height: 1px;
-// background-color: silver;
-// line-height: 2px;
-// }
-// }
-
-// .wrapper {
-// position: absolute;
-// pointer-events: all;
-// }
-
-// .menuicon {
-// display: inline-block;
-// border-right: 1px solid white(0, 0, 0, 0.2);
-// //color: rgb(19, 18, 18);
-// color: rgb(226, 21, 21);
-// line-height: 1;
-// padding: 0px 2px;
-// margin: 1px;
-// cursor: pointer;
-// text-align: center;
-// min-width: 10px;
-
-// }
-// .strong, .heading { font-weight: bold; }
-// .em { font-style: italic; }
-// .underline {text-decoration: underline}
-// .superscript {vertical-align:super}
-// .subscript { vertical-align:sub }
-// .strikethrough {text-decoration-line:line-through}
-// .font-size-indicator {
-// font-size: 12px;
-// padding-right: 0px;
-// }
-// .summarize{
-// color: white;
-// height: 20px;
-// text-align: center;
-// }
-
-// .brush{
-// display: inline-block;
-// width: 1em;
-// height: 1em;
-// stroke-width: 0;
-// stroke: currentColor;
-// fill: currentColor;
-// margin-right: 15px;
-// }
-
-// .brush-active{
-// display: inline-block;
-// width: 1em;
-// height: 1em;
-// stroke-width: 3;
-// stroke: greenyellow;
-// fill: greenyellow;
-// margin-right: 15px;
-// }
-
-// .dragger{
-// color: #eee;
-// margin-left: 5px;
-// } \ No newline at end of file
+} \ No newline at end of file
diff --git a/src/client/util/TooltipTextMenu.tsx b/src/client/util/TooltipTextMenu.tsx
index 564d9f0df..6001f9840 100644
--- a/src/client/util/TooltipTextMenu.tsx
+++ b/src/client/util/TooltipTextMenu.tsx
@@ -30,9 +30,8 @@ export class TooltipTextMenu {
public static Toolbar: HTMLDivElement | undefined;
- // editor state
+ // editor state properties
private view: EditorView;
- // private editorProps: FieldViewProps & FormattedTextBoxProps | undefined;
private fontStyles: MarkType[] = [];
private fontSizes: MarkType[] = [];
private listTypes: (NodeType | any)[] = [];
@@ -42,13 +41,16 @@ export class TooltipTextMenu {
private _activeMarks: Mark[] = [];
private _marksToDoms: Map<Mark, HTMLSpanElement> = new Map();
private _collapsed: boolean = false;
- //private link: HTMLAnchorElement;
// editor doms
public tooltip: HTMLElement = document.createElement("div");
private wrapper: HTMLDivElement = document.createElement("div");
// editor button doms
+ private colorDom?: Node;
+ private colorDropdownDom?: Node;
+ private highlightDom?: Node;
+ private highlightDropdownDom?: Node;
private linkEditor?: HTMLDivElement;
private linkText?: HTMLDivElement;
private linkDrag?: HTMLImageElement;
@@ -58,42 +60,32 @@ export class TooltipTextMenu {
private fontSizeDom?: Node;
private fontStyleDom?: Node;
private listTypeBtnDom?: Node;
- private colorDom?: Node;
- private colorDropdownDom?: Node;
- private highlightDom?: Node;
- private highlightDropdownDom?: Node;
-
-
- // private _collapseBtn?: MenuItem;
- // private _brushIsEmpty: boolean = true;
-
+ private basicTools?: HTMLElement;
constructor(view: EditorView) {
this.view = view;
- // // replace old active menu with this
- // if (TooltipTextMenuManager.Instance.activeMenu) {
- // TooltipTextMenuManager.Instance.activeMenu.wrapper.remove();
- // }
- // TooltipTextMenuManager.Instance.activeMenu = this;
-
- // initialize the tooltip
- this.createTooltip(view);
+ // initialize the tooltip -- sets this.tooltip
+ this.initTooltip(view);
// initialize the wrapper
this.wrapper = document.createElement("div");
this.wrapper.className = "wrapper";
this.wrapper.appendChild(this.tooltip);
- // positioning?
+ // initialize the dragger -- appends it to the wrapper
+ this.createDragger();
+
TooltipTextMenu.Toolbar = this.wrapper;
}
- private async createTooltip(view: EditorView) {
+ private async initTooltip(view: EditorView) {
// initialize tooltip dom
this.tooltip = document.createElement("div");
this.tooltip.className = "tooltipMenu";
+ this.basicTools = document.createElement("div");
+ this.basicTools.className = "basic-tools";
// init buttons to the tooltip -- paths to svgs are obtained from fontawesome
let items = [
@@ -113,12 +105,15 @@ export class TooltipTextMenu {
switch (dom.title) {
case "Bold":
this._marksToDoms.set(schema.mark(schema.marks.strong), dom);
+ this.basicTools && this.basicTools.appendChild(dom.cloneNode(true));
break;
case "Italic":
this._marksToDoms.set(schema.mark(schema.marks.em), dom);
+ this.basicTools && this.basicTools.appendChild(dom.cloneNode(true));
break;
case "Underline":
this._marksToDoms.set(schema.mark(schema.marks.underline), dom);
+ this.basicTools && this.basicTools.appendChild(dom.cloneNode(true));
break;
}
@@ -172,19 +167,12 @@ export class TooltipTextMenu {
this.tooltip.appendChild(this._brushDropdownDom);
// star
- // this.tooltip.appendChild(this.createLink().render(this.view).dom);
this.tooltip.appendChild(this.createStar().render(this.view).dom);
- //
+ // list types dropdown
this.updateListItemDropdown(":", this.listTypeBtnDom);
- //
await this.updateFromDash(view, undefined, undefined);
- // TooltipTextMenu.Toolbar = this.wrapper;
-
- // dragger
- // TODO: onclick handler in drag handles collapsing
- this.createDragger();
}
initFontStyles() {
@@ -224,13 +212,15 @@ export class TooltipTextMenu {
this.listTypes = Array.from(this.listTypeToIcon.keys());
}
+ // creates dragger element that allows dragging and collapsing (on double click)
+ // of editor and appends it to the wrapper
createDragger() {
- const dragger = document.createElement("div");
- dragger.className = "dragger";
-
let draggerWrapper = document.createElement("div");
draggerWrapper.className = "dragger-wrapper";
+ let dragger = document.createElement("div");
+ dragger.className = "dragger";
+
let line1 = document.createElement("span");
line1.className = "dragger-line";
let line2 = document.createElement("span");
@@ -238,14 +228,72 @@ export class TooltipTextMenu {
let line3 = document.createElement("span");
line3.className = "dragger-line";
- draggerWrapper.appendChild(line1);
- draggerWrapper.appendChild(line2);
- draggerWrapper.appendChild(line3);
+ dragger.appendChild(line1);
+ dragger.appendChild(line2);
+ dragger.appendChild(line3);
- dragger.appendChild(draggerWrapper);
+ draggerWrapper.appendChild(dragger);
- this.tooltip.appendChild(dragger);
- this.dragElement(dragger);
+ this.wrapper.appendChild(draggerWrapper);
+ this.dragElement(draggerWrapper);
+ }
+
+ dragElement(elmnt: HTMLElement) {
+ var pos1 = 0, pos2 = 0, pos3 = 0, pos4 = 0;
+ if (elmnt) {
+ // if present, the header is where you move the DIV from:
+ elmnt.onpointerdown = dragMouseDown;
+ elmnt.ondblclick = onClick;
+ }
+ const self = this;
+
+ function dragMouseDown(e: PointerEvent) {
+ e = e || window.event;
+ //e.preventDefault();
+ // get the mouse cursor position at startup:
+ pos3 = e.clientX;
+ pos4 = e.clientY;
+ document.onpointerup = closeDragElement;
+ // call a function whenever the cursor moves:
+ document.onpointermove = elementDrag;
+ }
+
+ function onClick(e: MouseEvent) {
+ self._collapsed = !self._collapsed;
+ const children = self.wrapper.childNodes;
+ if (self._collapsed && children.length > 0) {
+ self.wrapper.removeChild(self.tooltip);
+ self.basicTools && self.wrapper.prepend(self.basicTools);
+ }
+ else {
+ self.wrapper.prepend(self.tooltip);
+ self.basicTools && self.wrapper.removeChild(self.basicTools);
+ }
+ }
+
+ function elementDrag(e: PointerEvent) {
+ e = e || window.event;
+ //e.preventDefault();
+ // calculate the new cursor position:
+ pos1 = pos3 - e.clientX;
+ pos2 = pos4 - e.clientY;
+ pos3 = e.clientX;
+ pos4 = e.clientY;
+ // set the element's new position:
+ // elmnt.style.top = (elmnt.offsetTop - pos2) + "px";
+ // elmnt.style.left = (elmnt.offsetLeft - pos1) + "px";
+
+ self.wrapper.style.top = (self.wrapper.offsetTop - pos2) + "px";
+ self.wrapper.style.left = (self.wrapper.offsetLeft - pos1) + "px";
+ }
+
+ function closeDragElement() {
+ // stop moving when mouse button is released:
+ document.onpointerup = null;
+ document.onpointermove = null;
+ //self.highlightSearchTerms(self.state, ["hello"]);
+ //FormattedTextBox.Instance.unhighlightSearchTerms();
+ }
}
//label of dropdown will change to given label
@@ -261,7 +309,7 @@ export class TooltipTextMenu {
let newfontSizeDom = (new Dropdown(cut(fontSizeBtns), {
label: label,
- css: "color:black; min-width: 60px; padding-left: 5px; margin-right: 0;"
+ css: "color:black; min-width: 60px;"
}) as MenuItem).render(this.view).dom;
if (this.fontSizeDom) { this.tooltip.replaceChild(newfontSizeDom, this.fontSizeDom); }
else {
@@ -270,8 +318,6 @@ export class TooltipTextMenu {
this.fontSizeDom = newfontSizeDom;
}
- // Make the DIV element draggable
-
//label of dropdown will change to given label
updateFontStyleDropdown(label: string) {
//filtering function - might be unecessary
@@ -285,7 +331,7 @@ export class TooltipTextMenu {
let newfontStyleDom = (new Dropdown(cut(fontBtns), {
label: label,
- css: "color:black; width: 125px; margin-left: -3px; padding-left: 2px;"
+ css: "color:black; width: 125px;"
}) as MenuItem).render(this.view).dom;
if (this.fontStyleDom) { this.tooltip.replaceChild(newfontStyleDom, this.fontStyleDom); }
else {
@@ -299,11 +345,7 @@ export class TooltipTextMenu {
if (!this.linkEditor || !this.linkText) {
this.linkEditor = document.createElement("div");
this.linkEditor.className = "ProseMirror-icon menuicon";
- // this.linkEditor.style.color = "black";
this.linkText = document.createElement("div");
- // this.linkText.style.cssFloat = "left";
- // this.linkText.style.marginRight = "5px";
- // this.linkText.style.marginLeft = "5px";
this.linkText.setAttribute("contenteditable", "true");
this.linkText.style.whiteSpace = "nowrap";
this.linkText.style.width = "150px";
@@ -391,13 +433,11 @@ export class TooltipTextMenu {
e.preventDefault();
}
};
- // this.tooltip.appendChild(this.linkEditor);
}
async getTextLinkTargetTitle() {
let node = this.view.state.selection.$from.nodeAfter;
let link = node && node.marks.find(m => m.type.name === "link");
- // let href = link!.attrs.href;
if (link) {
let href = link.attrs.href;
if (href) {
@@ -445,7 +485,6 @@ export class TooltipTextMenu {
input.type = "text";
input.placeholder = "Enter URL";
- console.log(targetTitle);
if (targetTitle) input.value = targetTitle;
input.onclick = (e: MouseEvent) => {
input.select();
@@ -514,62 +553,6 @@ export class TooltipTextMenu {
return linkDropdown;
}
- dragElement(elmnt: HTMLElement) {
- var pos1 = 0, pos2 = 0, pos3 = 0, pos4 = 0;
- if (elmnt) {
- // if present, the header is where you move the DIV from:
- elmnt.onpointerdown = dragMouseDown;
- elmnt.ondblclick = onClick;
- }
- const self = this;
-
- function dragMouseDown(e: PointerEvent) {
- e = e || window.event;
- //e.preventDefault();
- // get the mouse cursor position at startup:
- pos3 = e.clientX;
- pos4 = e.clientY;
- document.onpointerup = closeDragElement;
- // call a function whenever the cursor moves:
- document.onpointermove = elementDrag;
- }
-
- function onClick(e: MouseEvent) {
- self._collapsed = !self._collapsed;
- const children = self.wrapper.childNodes;
- if (self._collapsed && children.length > 1) {
- self.wrapper.removeChild(self.tooltip);
- }
- else {
- self.wrapper.appendChild(self.tooltip);
- }
- }
-
- function elementDrag(e: PointerEvent) {
- e = e || window.event;
- //e.preventDefault();
- // calculate the new cursor position:
- pos1 = pos3 - e.clientX;
- pos2 = pos4 - e.clientY;
- pos3 = e.clientX;
- pos4 = e.clientY;
- // set the element's new position:
- // elmnt.style.top = (elmnt.offsetTop - pos2) + "px";
- // elmnt.style.left = (elmnt.offsetLeft - pos1) + "px";
-
- self.wrapper.style.top = (self.wrapper.offsetTop - pos2) + "px";
- self.wrapper.style.left = (self.wrapper.offsetLeft - pos1) + "px";
- }
-
- function closeDragElement() {
- // stop moving when mouse button is released:
- document.onpointerup = null;
- document.onpointermove = null;
- //self.highlightSearchTerms(self.state, ["hello"]);
- //FormattedTextBox.Instance.unhighlightSearchTerms();
- }
- }
-
// makeLinkWithState = (state: EditorState, target: string, location: string) => {
// let link = state.schema.mark(state.schema.marks.link, { href: target, location: location });
// }
@@ -616,10 +599,70 @@ export class TooltipTextMenu {
}
}
}
+ }
-
+ deleteLinkItem() {
+ const icon = {
+ height: 16, width: 16,
+ path: "M15.898,4.045c-0.271-0.272-0.713-0.272-0.986,0l-4.71,4.711L5.493,4.045c-0.272-0.272-0.714-0.272-0.986,0s-0.272,0.714,0,0.986l4.709,4.711l-4.71,4.711c-0.272,0.271-0.272,0.713,0,0.986c0.136,0.136,0.314,0.203,0.492,0.203c0.179,0,0.357-0.067,0.493-0.203l4.711-4.711l4.71,4.711c0.137,0.136,0.314,0.203,0.494,0.203c0.178,0,0.355-0.067,0.492-0.203c0.273-0.273,0.273-0.715,0-0.986l-4.711-4.711l4.711-4.711C16.172,4.759,16.172,4.317,15.898,4.045z"
+ };
+ return new MenuItem({
+ title: "Delete Link",
+ label: "X",
+ icon: icon,
+ css: "color: red",
+ class: "summarize",
+ execEvent: "",
+ run: (state, dispatch) => {
+ this.deleteLink();
+ }
+ });
}
+ createLink() {
+ let markType = schema.marks.link;
+ return new MenuItem({
+ title: "Add or remove link",
+ label: "Add or remove link",
+ execEvent: "",
+ icon: icons.link,
+ css: "color:white;",
+ class: "menuicon",
+ enable(state) { return !state.selection.empty; },
+ run: (state, dispatch, view) => {
+ // to remove link
+ let curLink = "";
+ if (this.markActive(state, markType)) {
+
+ let { from, $from, to, empty } = state.selection;
+ let node = state.doc.nodeAt(from);
+ node && node.marks.map(m => {
+ m.type === markType && (curLink = m.attrs.href);
+ });
+ //toggleMark(markType)(state, dispatch);
+ //return true;
+ }
+ // to create link
+ openPrompt({
+ title: "Create a link",
+ fields: {
+ href: new TextField({
+ value: curLink,
+ label: "Link Target",
+ required: true
+ }),
+ title: new TextField({ label: "Title" })
+ },
+ callback(attrs: any) {
+ toggleMark(markType, attrs)(view.state, view.dispatch);
+ view.focus();
+ },
+ flyout_top: 0,
+ flyout_left: 0
+ });
+ }
+ });
+ }
//will display a remove-list-type button if selection is in list, otherwise will show list type dropdown
updateListItemDropdown(label: string, listTypeBtn: any) {
@@ -644,108 +687,6 @@ export class TooltipTextMenu {
return listTypeBtn;
}
- //for a specific grouping of marks (passed in), remove all and apply the passed-in one to the selected text
- changeToMarkInGroup = (markType: MarkType | undefined, view: EditorView, fontMarks: MarkType[]) => {
- let { $cursor, ranges } = view.state.selection as TextSelection;
- let state = view.state;
- let dispatch = view.dispatch;
-
- //remove all other active font marks
- fontMarks.forEach((type) => {
- if (dispatch) {
- if ($cursor) {
- if (type.isInSet(state.storedMarks || $cursor.marks())) {
- dispatch(state.tr.removeStoredMark(type));
- }
- } else {
- let has = false;
- for (let i = 0; !has && i < ranges.length; i++) {
- let { $from, $to } = ranges[i];
- has = state.doc.rangeHasMark($from.pos, $to.pos, type);
- }
- for (let i of ranges) {
- if (has) {
- toggleMark(type)(view.state, view.dispatch, view);
- }
- }
- }
- }
- });
-
- if (markType) {
- // fontsize
- if (markType.name[0] === 'p') {
- let size = this.fontSizeToNum.get(markType);
- if (size) { this.updateFontSizeDropdown(String(size) + " pt"); }
- if (this.editorProps) {
- let ruleProvider = this.editorProps.ruleProvider;
- let heading = NumCast(this.editorProps.Document.heading);
- if (ruleProvider && heading) {
- ruleProvider["ruleSize_" + heading] = size;
- }
- }
- }
- else {
- let fontName = this.fontStylesToName.get(markType);
- if (fontName) { this.updateFontStyleDropdown(fontName); }
- if (this.editorProps) {
- let ruleProvider = this.editorProps.ruleProvider;
- let heading = NumCast(this.editorProps.Document.heading);
- if (ruleProvider && heading) {
- ruleProvider["ruleFont_" + heading] = fontName;
- }
- }
- }
- //actually apply font
- if ((view.state.selection as any).node && (view.state.selection as any).node.type === view.state.schema.nodes.ordered_list) {
- let status = updateBullets(view.state.tr.setNodeMarkup(view.state.selection.from, (view.state.selection as any).node.type,
- { ...(view.state.selection as NodeSelection).node.attrs, setFontFamily: markType.name, setFontSize: Number(markType.name.replace(/p/, "")) }), view.state.schema);
- view.dispatch(status.setSelection(new NodeSelection(status.doc.resolve(view.state.selection.from))));
- }
- else toggleMark(markType)(view.state, view.dispatch, view);
- }
- }
-
- //remove all node typeand apply the passed-in one to the selected text
- changeToNodeType = (nodeType: NodeType | undefined, view: EditorView) => {
- //remove oldif (nodeType) { //add new
- if (nodeType === schema.nodes.bullet_list) {
- wrapInList(nodeType)(view.state, view.dispatch);
- } else {
- var marks = view.state.storedMarks || (view.state.selection.$to.parentOffset && view.state.selection.$from.marks());
- if (!wrapInList(schema.nodes.ordered_list)(view.state, (tx2: any) => {
- let tx3 = updateBullets(tx2, schema, (nodeType as any).attrs.mapStyle);
- marks && tx3.ensureMarks([...marks]);
- marks && tx3.setStoredMarks([...marks]);
-
- view.dispatch(tx2);
- })) {
- let tx2 = view.state.tr;
- let tx3 = nodeType ? updateBullets(tx2, schema, (nodeType as any).attrs.mapStyle) : tx2;
- marks && tx3.ensureMarks([...marks]);
- marks && tx3.setStoredMarks([...marks]);
-
- view.dispatch(tx3);
- }
- }
- }
-
- //makes a button for the drop down FOR MARKS
- //css is the style you want applied to the button
- dropdownMarkBtn(label: string, css: string, markType: MarkType, view: EditorView, changeToMarkInGroup: (markType: MarkType<any>, view: EditorView, groupMarks: MarkType[]) => any, groupMarks: MarkType[]) {
- return new MenuItem({
- title: "",
- label: label,
- execEvent: "",
- class: "menuicon",
- css: css,
- enable() { return true; },
- run() {
- changeToMarkInGroup(markType, view, groupMarks);
- }
- });
- }
-
createStar() {
return new MenuItem({
title: "Summarize",
@@ -772,6 +713,17 @@ export class TooltipTextMenu {
return true;
}
+ public static insertComment(state: EditorState<any>, dispatch: any) {
+ if (state.selection.empty) return false;
+ let mark = state.schema.marks.highlight.create();
+ let tr = state.tr;
+ tr.addMark(state.selection.from, state.selection.to, mark);
+ let content = tr.selection.content();
+ let newNode = state.schema.nodes.star.create({ visibility: false, text: content, textslice: content.toJSON() });
+ dispatch && dispatch(tr.replaceSelectionWith(newNode).removeMark(tr.selection.from - 1, tr.selection.from, mark));
+ return true;
+ }
+
createHighlightTool() {
return new MenuItem({
title: "Highlight",
@@ -975,24 +927,6 @@ export class TooltipTextMenu {
return colorDropdown;
}
- deleteLinkItem() {
- const icon = {
- height: 16, width: 16,
- path: "M15.898,4.045c-0.271-0.272-0.713-0.272-0.986,0l-4.71,4.711L5.493,4.045c-0.272-0.272-0.714-0.272-0.986,0s-0.272,0.714,0,0.986l4.709,4.711l-4.71,4.711c-0.272,0.271-0.272,0.713,0,0.986c0.136,0.136,0.314,0.203,0.492,0.203c0.179,0,0.357-0.067,0.493-0.203l4.711-4.711l4.71,4.711c0.137,0.136,0.314,0.203,0.494,0.203c0.178,0,0.355-0.067,0.492-0.203c0.273-0.273,0.273-0.715,0-0.986l-4.711-4.711l4.711-4.711C16.172,4.759,16.172,4.317,15.898,4.045z"
- };
- return new MenuItem({
- title: "Delete Link",
- label: "X",
- icon: icon,
- css: "color: red",
- class: "summarize",
- execEvent: "",
- run: (state, dispatch) => {
- this.deleteLink();
- }
- });
- }
-
createBrush(active: boolean = false) {
const icon = {
height: 32, width: 32,
@@ -1020,8 +954,6 @@ export class TooltipTextMenu {
});
}
- // selectionchanged event handler
-
brush_function(state: EditorState<any>, dispatch: any) {
if (TooltipTextMenuManager.Instance._brushIsEmpty) {
const selected_marks = this.getMarksInSelection(this.view.state);
@@ -1055,8 +987,6 @@ export class TooltipTextMenu {
}
}
}
-
-
}
createBrushDropdown(active: boolean = false) {
@@ -1120,88 +1050,106 @@ export class TooltipTextMenu {
return brushDom;
}
- // createCollapse() {
- // this._collapseBtn = new MenuItem({
- // title: "Collapse",
- // //label: "Collapse",
- // icon: icons.join,
- // execEvent: "",
- // css: "color:white;",
- // class: "summarize",
- // run: () => {
- // this.collapseToolTip();
- // }
- // });
- // }
- // collapseToolTip() {
- // if (this._collapseBtn) {
- // if (this._collapseBtn.spec.title === "Collapse") {
- // // const newcollapseBtn = new MenuItem({
- // // title: "Expand",
- // // icon: icons.join,
- // // execEvent: "",
- // // css: "color:white;",
- // // class: "summarize",
- // // run: (state, dispatch, view) => {
- // // this.collapseToolTip();
- // // }
- // // });
- // // this.tooltip.replaceChild(newcollapseBtn.render(this.view).dom, this._collapseBtn.render(this.view).dom);
- // // this._collapseBtn = newcollapseBtn;
- // this.tooltip.style.width = "30px";
- // this._collapseBtn.spec.title = "Expand";
- // this._collapseBtn.render(this.view);
- // }
- // else {
- // this._collapseBtn.spec.title = "Collapse";
- // this.tooltip.style.width = "550px";
- // this._collapseBtn.render(this.view);
- // }
- // }
- // }
- createLink() {
- let markType = schema.marks.link;
- return new MenuItem({
- title: "Add or remove link",
- label: "Add or remove link",
- execEvent: "",
- icon: icons.link,
- css: "color:white;",
- class: "menuicon",
- enable(state) { return !state.selection.empty; },
- run: (state, dispatch, view) => {
- // to remove link
- let curLink = "";
- if (this.markActive(state, markType)) {
+ //for a specific grouping of marks (passed in), remove all and apply the passed-in one to the selected text
+ changeToMarkInGroup = (markType: MarkType | undefined, view: EditorView, fontMarks: MarkType[]) => {
+ let { $cursor, ranges } = view.state.selection as TextSelection;
+ let state = view.state;
+ let dispatch = view.dispatch;
- let { from, $from, to, empty } = state.selection;
- let node = state.doc.nodeAt(from);
- node && node.marks.map(m => {
- m.type === markType && (curLink = m.attrs.href);
- });
- //toggleMark(markType)(state, dispatch);
- //return true;
+ //remove all other active font marks
+ fontMarks.forEach((type) => {
+ if (dispatch) {
+ if ($cursor) {
+ if (type.isInSet(state.storedMarks || $cursor.marks())) {
+ dispatch(state.tr.removeStoredMark(type));
+ }
+ } else {
+ let has = false;
+ for (let i = 0; !has && i < ranges.length; i++) {
+ let { $from, $to } = ranges[i];
+ has = state.doc.rangeHasMark($from.pos, $to.pos, type);
+ }
+ for (let i of ranges) {
+ if (has) {
+ toggleMark(type)(view.state, view.dispatch, view);
+ }
+ }
}
- // to create link
- openPrompt({
- title: "Create a link",
- fields: {
- href: new TextField({
- value: curLink,
- label: "Link Target",
- required: true
- }),
- title: new TextField({ label: "Title" })
- },
- callback(attrs: any) {
- toggleMark(markType, attrs)(view.state, view.dispatch);
- view.focus();
- },
- flyout_top: 0,
- flyout_left: 0
- });
+ }
+ });
+
+ if (markType) {
+ // fontsize
+ if (markType.name[0] === 'p') {
+ let size = this.fontSizeToNum.get(markType);
+ if (size) { this.updateFontSizeDropdown(String(size) + " pt"); }
+ if (this.editorProps) {
+ let ruleProvider = this.editorProps.ruleProvider;
+ let heading = NumCast(this.editorProps.Document.heading);
+ if (ruleProvider && heading) {
+ ruleProvider["ruleSize_" + heading] = size;
+ }
+ }
+ }
+ else {
+ let fontName = this.fontStylesToName.get(markType);
+ if (fontName) { this.updateFontStyleDropdown(fontName); }
+ if (this.editorProps) {
+ let ruleProvider = this.editorProps.ruleProvider;
+ let heading = NumCast(this.editorProps.Document.heading);
+ if (ruleProvider && heading) {
+ ruleProvider["ruleFont_" + heading] = fontName;
+ }
+ }
+ }
+ //actually apply font
+ if ((view.state.selection as any).node && (view.state.selection as any).node.type === view.state.schema.nodes.ordered_list) {
+ let status = updateBullets(view.state.tr.setNodeMarkup(view.state.selection.from, (view.state.selection as any).node.type,
+ { ...(view.state.selection as NodeSelection).node.attrs, setFontFamily: markType.name, setFontSize: Number(markType.name.replace(/p/, "")) }), view.state.schema);
+ view.dispatch(status.setSelection(new NodeSelection(status.doc.resolve(view.state.selection.from))));
+ }
+ else toggleMark(markType)(view.state, view.dispatch, view);
+ }
+ }
+
+ //remove all node typeand apply the passed-in one to the selected text
+ changeToNodeType = (nodeType: NodeType | undefined, view: EditorView) => {
+ //remove oldif (nodeType) { //add new
+ if (nodeType === schema.nodes.bullet_list) {
+ wrapInList(nodeType)(view.state, view.dispatch);
+ } else {
+ var marks = view.state.storedMarks || (view.state.selection.$to.parentOffset && view.state.selection.$from.marks());
+ if (!wrapInList(schema.nodes.ordered_list)(view.state, (tx2: any) => {
+ let tx3 = updateBullets(tx2, schema, (nodeType as any).attrs.mapStyle);
+ marks && tx3.ensureMarks([...marks]);
+ marks && tx3.setStoredMarks([...marks]);
+
+ view.dispatch(tx2);
+ })) {
+ let tx2 = view.state.tr;
+ let tx3 = nodeType ? updateBullets(tx2, schema, (nodeType as any).attrs.mapStyle) : tx2;
+ marks && tx3.ensureMarks([...marks]);
+ marks && tx3.setStoredMarks([...marks]);
+
+ view.dispatch(tx3);
+ }
+ }
+ }
+
+ //makes a button for the drop down FOR MARKS
+ //css is the style you want applied to the button
+ dropdownMarkBtn(label: string, css: string, markType: MarkType, view: EditorView, changeToMarkInGroup: (markType: MarkType<any>, view: EditorView, groupMarks: MarkType[]) => any, groupMarks: MarkType[]) {
+ return new MenuItem({
+ title: "",
+ label: label,
+ execEvent: "",
+ class: "dropdown-item",
+ css: css,
+ enable() { return true; },
+ run() {
+ changeToMarkInGroup(markType, view, groupMarks);
}
});
}
@@ -1213,7 +1161,7 @@ export class TooltipTextMenu {
title: "",
label: label,
execEvent: "",
- class: "menuicon",
+ class: "dropdown-item",
css: css,
enable() { return true; },
run() {
@@ -1390,35 +1338,12 @@ export class TooltipTextMenu {
update_mark_doms() {
this.reset_mark_doms();
- let foundlink = false;
- // let children = this.extras.childNodes;
this._activeMarks.forEach((mark) => {
if (this._marksToDoms.has(mark)) {
let dom = this._marksToDoms.get(mark);
if (dom) dom.style.color = "greenyellow";
}
- // if (children.length > 1) {
- // foundlink = true;
- // }
- // if (mark.type.name === "link" && children.length === 1) {
- // // let del = document.createElement("button");
- // // del.textContent = "X";
- // // del.style.color = "red";
- // // del.style.height = "10px";
- // // del.style.width = "10px";
- // // del.style.marginLeft = "5px";
- // // del.onclick = this.deleteLink;
- // // this.extras.appendChild(del);
- // let del = this.deleteLinkItem().render(this.view).dom;
- // this.extras.appendChild(del);
- // foundlink = true;
- // }
});
- // if (!foundlink) {
- // if (children.length > 1) {
- // this.extras.removeChild(children[1]);
- // }
- // }
// keeps brush tool highlighted if active when switching between textboxes
if (!TooltipTextMenuManager.Instance._brushIsEmpty) {
@@ -1535,30 +1460,11 @@ class TooltipTextMenuManager {
return TooltipTextMenuManager._instance;
}
- // private pinnedToUnpinned() {
- // let position = MainOverlayTextBox.Instance.position;
-
- // this.unpinnedX = this.pinnedX - position[0];
- // this.unpinnedY = this.pinnedY - position[1];
- // }
-
- // private unpinnedToPinned() {
- // let position = MainOverlayTextBox.Instance.position;
-
- // this.pinnedX = position[0] + this.unpinnedX;
- // this.pinnedY = position[1] + this.unpinnedY;
- // }
-
public get isPinned() {
return this._isPinned;
}
public toggleIsPinned() {
- // if (this._isPinned) {
- // this.pinnedToUnpinned();
- // } else {
- // this.unpinnedToPinned();
- // }
this._isPinned = !this._isPinned;
}
}