From d7ead10b566e7de121b2cd2c99fecca8469d63b8 Mon Sep 17 00:00:00 2001 From: Armen Kesablyan Date: Tue, 7 Feb 2012 16:30:47 -0800 Subject: Initial Text tool completion. --- .../text-properties.reel/text-properties.css | 4 +- .../text-properties.reel/text-properties.html | 202 +++++++++++++----- .../text-properties.reel/text-properties.js | 149 ++++++++++++- js/tools/TextTool.js | 47 ++-- .../ui/rich-text-editor.reel/shortcut-manager.js | 237 +++++++++++++++++++++ 5 files changed, 553 insertions(+), 86 deletions(-) create mode 100644 node_modules/montage/ui/rich-text-editor.reel/shortcut-manager.js diff --git a/js/components/tools-properties/text-properties.reel/text-properties.css b/js/components/tools-properties/text-properties.reel/text-properties.css index d581c6c3..2eb608d3 100644 --- a/js/components/tools-properties/text-properties.reel/text-properties.css +++ b/js/components/tools-properties/text-properties.reel/text-properties.css @@ -30,4 +30,6 @@ font-size:11px; } - +.optionsTextTool .fontSelection { + width:100px; +} \ No newline at end of file diff --git a/js/components/tools-properties/text-properties.reel/text-properties.html b/js/components/tools-properties/text-properties.reel/text-properties.html index fb57c06d..14123b12 100644 --- a/js/components/tools-properties/text-properties.reel/text-properties.html +++ b/js/components/tools-properties/text-properties.reel/text-properties.html @@ -33,8 +33,8 @@ "alignCenter": {"@": "alignCenter"}, "alignRight": {"@": "alignRight"}, "alignJustify": {"@": "alignJustify"}, - "indentRight": {"@": "indentRight"}, - "indentLeft": {"@": "indentLeft"}, + "indent": {"@": "indent"}, + "outdent": {"@": "outdent"}, "numberedList": {"@": "numberedList"}, "bulletedList": {"@": "bulletedList"} } @@ -57,8 +57,16 @@ "module": "js/components/combobox.reel", "name": "Combobox", "properties": { - "element": {"#": "fontSelection"} - } + "element": {"#": "fontSelection"}, + "identifier": "fontSelection" + }, + "listeners": [ + { + "type": "change", + "listener": {"@": "owner"} + } + ] + }, "fontSettings": { "module": "js/components/button.reel", @@ -72,48 +80,90 @@ "module": "js/components/hottextunit.reel", "name": "HotTextUnit", "properties": { - "element": {"#": "fontSize"} - } - }, + "element": {"#": "fontSize"}, + "value": 12, + "identifier": "fontSize" + }, + "listeners": [ + { + "type": "change", + "listener": {"@": "owner"} + }, + { + "type": "changing", + "listener": {"@": "owner"} + } + ] - "fontColor": { - "module": "js/components/button.reel", - "name": "Button", - "properties": { - "element": {"#": "fontColor"} - } }, + + "fontColor": { + "module" : "js/components/ui/color-chip.reel", + "name" : "ColorChip", + "properties" : { + "element" : {"#": "fontColor"}, + "mode": "chip" + } + }, "btnBold": { "module": "js/components/button.reel", "name": "Button", "properties": { "element": {"#": "btnBold"}, - "_isToggleButton": true - } + "_isToggleButton": true, + "identifier": "btnBold" + }, + "listeners": [ + { + "type": "action", + "listener": {"@": "owner"} + } + ] }, "btnItalic": { "module": "js/components/button.reel", "name": "Button", "properties": { "element": {"#": "btnItalic"}, - "_isToggleButton": true - } + "_isToggleButton": true, + "identifier": "btnItalic" + }, + "listeners": [ + { + "type": "action", + "listener": {"@": "owner"} + } + ] }, "btnUnderline": { "module": "js/components/button.reel", "name": "Button", "properties": { "element": {"#": "btnUnderline"}, - "_isToggleButton": true - } + "_isToggleButton": true, + "identifier": "btnUnderline" + }, + "listeners": [ + { + "type": "action", + "listener": {"@": "owner"} + } + ] }, "btnStrikethrough": { "module": "js/components/button.reel", "name": "Button", "properties": { "element": {"#": "btnStrikethrough"}, - "_isToggleButton": true - } + "_isToggleButton": true, + "identifier": "btnStrikethrough" + }, + "listeners": [ + { + "type": "action", + "listener": {"@": "owner"} + } + ] }, "txtLink": { "module": "js/components/textfield.reel", @@ -134,66 +184,106 @@ "module": "js/components/button.reel", "name": "Button", "properties": { - "element": {"#": "alignLeft"} - } + "element": {"#": "alignLeft"}, + "_isToggleButton": true, + "identifier": "alignLeft" + }, + "listeners": [ + { + "type": "action", + "listener": {"@": "owner"} + } + ] }, "alignCenter": { "module": "js/components/button.reel", "name": "Button", "properties": { - "element": {"#": "alignCenter"} - } + "element": {"#": "alignCenter"}, + "_isToggleButton": true, + "identifier": "alignCenter" + }, + "listeners": [ + { + "type": "action", + "listener": {"@": "owner"} + } + ] }, "alignRight": { "module": "js/components/button.reel", "name": "Button", "properties": { - "element": {"#": "alignRight"} - } + "element": {"#": "alignRight"}, + "_isToggleButton": true, + "identifier": "alignRight" + }, + "listeners": [ + { + "type": "action", + "listener": {"@": "owner"} + } + ] }, "alignJustify": { "module": "js/components/button.reel", "name": "Button", "properties": { - "element": {"#": "alignJustify"} - } + "element": {"#": "alignJustify"}, + "_isToggleButton": true, + "identifier": "alignJustify" + }, + "listeners": [ + { + "type": "action", + "listener": {"@": "owner"} + } + ] }, - "indentRight": { + "indent": { "module": "js/components/button.reel", "name": "Button", "properties": { - "element": {"#": "indentRight"} + "element": {"#": "indent"} } }, - "indentLeft": { + "outdent": { "module": "js/components/button.reel", "name": "Button", "properties": { - "element": {"#": "indentLeft"} + "element": {"#": "outdent"} } }, "bulletedList": { "module": "js/components/button.reel", "name": "Button", "properties": { - "element": {"#": "bulletedList"} - } + "element": {"#": "bulletedList"}, + "_isToggleButton": true, + "identifier": "bulletedList" + }, + "listeners": [ + { + "type": "action", + "listener": {"@": "owner"} + } + ] }, "numberedList": { "module": "js/components/button.reel", "name": "Button", "properties": { - "element": {"#": "numberedList"} - } - }, - "fontColor": { - "module" : "js/components/ui/color-chip.reel", - "name" : "ColorChip", - "properties" : { - "element" : {"#": "fontColor"}, - "mode": "chip" - } - } + "element": {"#": "numberedList"}, + "_isToggleButton": true, + "identifier": "numberedList" + }, + "listeners": [ + { + "type": "action", + "listener": {"@": "owner"} + } + ] + } } @@ -202,16 +292,16 @@
- - - - + + + + - - + + - + @@ -223,10 +313,10 @@ +
- - - + + diff --git a/js/components/tools-properties/text-properties.reel/text-properties.js b/js/components/tools-properties/text-properties.reel/text-properties.js index 313693b1..de0b5fa3 100644 --- a/js/components/tools-properties/text-properties.reel/text-properties.js +++ b/js/components/tools-properties/text-properties.reel/text-properties.js @@ -25,8 +25,8 @@ exports.TextProperties = Montage.create(ToolProperties, { alignCenter: {value: null}, alignRight: {value: null}, alignJustify: {value: null}, - indentRight: {value: null}, - indentLeft: {value: null}, + indent: {value: null}, + outdent: {value: null}, numberedList: {value: null}, bulletedList: {value: null}, @@ -42,9 +42,34 @@ exports.TextProperties = Montage.create(ToolProperties, { this.alignCenter.label = "Center"; this.alignRight.label = "Right"; this.alignJustify.label = "Justify"; + this.indent.label = "-->" + this.outdent.label = "<--"; + this.numberedList.label = "1 2 3"; + this.bulletedList.label = "• • •"; + this.fontSelection.items = ["Arial", "Arial Black", "Courier New", "Garamond", "Georgia", "Open Sans", "Tahoma", "Times New Roman", "Trebuchet MS", "Verdana"]; + this.tagType.items = ["div", "span", "p", "section", "article", "h1", "h2", "h3", "h4", "h5", "h6"]; + + + this.application.ninja.stage.textTool.addEventListener("editorSelect", this, false); + Object.defineBinding(this.application.ninja.stage.textTool.states, "bold", { + boundObject: this.btnBold, + boundObjectPropertyPath: "value" + }); + } }, - + + handleEditorSelect: { + value: function(e) { + console.log("hello"); + this.application.ninja.stage.textTool.updateStates(); + } + }, + + defaultFontSize: { + value: "12px" + }, + _subPrepare: { value: function() { //this.divElement.addEventListener("click", this, false); @@ -54,6 +79,122 @@ exports.TextProperties = Montage.create(ToolProperties, { handleClick: { value: function(event) { // this.selectedElement = event._event.target.id; + + } + }, + + handleFontSizeChange: { + + }, + + handleBtnBoldAction: { + value: function(e) { + this.application.ninja.stage.textTool.doAction("bold", true); + } + }, + + handleBtnItalicAction: { + value: function(e) { + this.application.ninja.stage.textTool.doAction("italic", true); + } + }, + + handleBtnUnderlineAction: { + value: function(e) { + this.application.ninja.stage.textTool.doAction("underline", true); + } + }, + + handleBtnStrikethroughAction: { + value: function(e) { + this.application.ninja.stage.textTool.doAction("strikethrough", true); + } + }, + + handleAlignLeftAction: { + value: function(e) { + //this.alignLeft.value = false; + this.alignCenter.value = false; + this.alignRight.value = false; + this.alignJustify.value = false; + this.application.ninja.stage.textTool.doAction("justifyLeft", true); + } + }, + + handleAlignCenterAction: { + value: function(e) { + this.alignLeft.value = false; + //this.alignCenter.value = false; + this.alignRight.value = false; + this.alignJustify.value = false; + this.application.ninja.stage.textTool.doAction("justifyCenter", true); } - } + }, + + handleAlignRightAction: { + value: function(e) { + this.alignLeft.value = false; + this.alignCenter.value = false; + //this.alignRight.value = false; + this.alignJustify.value = false; + this.application.ninja.stage.textTool.doAction("justifyRight", true); + } + }, + + handleAlignJustifyAction: { + value: function(e) { + this.alignLeft.value = false; + this.alignCenter.value = false; + this.alignRight.value = false; + //this.alignJustify.value = false; + this.application.ninja.stage.textTool.doAction("strikethrough", null); + } + }, + + handleIndentAction: { + value: function(e) { + this.application.ninja.stage.textTool.doAction("indent", null); + } + }, + + handleOutdentAction: { + value: function(e) { + this.application.ninja.stage.textTool.doAction("outdent", null); + } + }, + + handleFontSizeChange: { + value: function(e) { + + } + }, + + handleFontSizeChanging: { + value: function(e) { + + } + }, + + handleFontSelectionChange: { + value: function() { + this.application.ninja.stage.textTool.doAction("fontname", this.fontSelection.value); + } + }, + + handleNumberedListAction: { + value: function(e) { + //this.numberedList.value = false; + this.bulletedList.value = false; + this.application.ninja.stage.textTool.doAction("insertnumberedlist", true); + } + }, + + handleOrderedListAction: { + value: function(e) { + this.numberedList.value = false; + //this.bulletedList.value = false; + this.application.ninja.stage.textTool.doAction("insertnumberedlist", true); + } + }, + }); \ No newline at end of file diff --git a/js/tools/TextTool.js b/js/tools/TextTool.js index 8b48ff4f..28e7ddf3 100644 --- a/js/tools/TextTool.js +++ b/js/tools/TextTool.js @@ -17,10 +17,20 @@ exports.TextTool = Montage.create(DrawingTool, { return this._selectedElement; }, set: function(val) { - if(this._selectedElement !== null) { - + if (this._selectedElement !== null) { + this.selectedElement.innerHTML = this.application.ninja.stage.textTool.value; + this.application.ninja.stage.textTool.value = ""; + this.application.ninja.stage.textTool.element.style.display = "none"; } + //Set Selected Element this._selectedElement = val; + if(val !== null) { + this.drawTextTool(); + this.handleScroll(); + this.application.ninja.stage._iframeContainer.addEventListener("scroll", this, false); + } else { + this.application.ninja.stage._iframeContainer.removeEventListener("scroll", this); + } } }, @@ -29,11 +39,19 @@ exports.TextTool = Montage.create(DrawingTool, { HandleLeftButtonDown: { value: function(event) { - this.deselectText(); this.startDraw(event); } }, + handleScroll: { + value: function(e) { + // Set Top & Left Positions + var textToolCoordinates = this.application.ninja.stage.toViewportCoordinates(this.selectedElement.offsetLeft, this.selectedElement.offsetTop); + this.application.ninja.stage.textTool.element.style.left = textToolCoordinates[0] + "px"; + this.application.ninja.stage.textTool.element.style.top = textToolCoordinates[1] + "px"; + } + }, + HandleMouseMove: { value: function(event) { if(this._escape) { @@ -73,12 +91,9 @@ exports.TextTool = Montage.create(DrawingTool, { this.endDraw(event); } else { this.doSelection(event); - console.log("im here"); if (this.application.ninja.selectedElements.length !== 0 ) { this.selectedElement = this.application.ninja.selectedElements[0]._element; - this.drawTextTool(); } - this._isDrawing = false; } } @@ -88,7 +103,6 @@ exports.TextTool = Montage.create(DrawingTool, { value: function(fromElement, toElement, styles) { styles.forEach(function(style) { var styleCamelCase = style.replace(/(\-[a-z])/g, function($1){return $1.toUpperCase().replace('-','');}); - console.log(styleCamelCase, style, window.getComputedStyle(fromElement)[style]); toElement.style[styleCamelCase] = window.getComputedStyle(fromElement)[style]; }, this); } @@ -96,7 +110,6 @@ exports.TextTool = Montage.create(DrawingTool, { drawTextTool: { value: function() { - console.log(" now im here"); this.application.ninja.stage.textTool.value = this.selectedElement.innerHTML; if(this.application.ninja.stage.textTool.value === "") { this.application.ninja.stage.textTool.value = " "; } this.selectedElement.innerHTML = ""; @@ -105,11 +118,6 @@ exports.TextTool = Montage.create(DrawingTool, { this.application.ninja.stage.textTool.element.style.display = "block"; this.application.ninja.stage.textTool.element.style.position = "absolute"; - // Set Top & Left Positions - var textToolCoordinates = this.application.ninja.stage.toViewportCoordinates(this.selectedElement.offsetLeft, this.selectedElement.offsetTop); - this.application.ninja.stage.textTool.element.style.left = textToolCoordinates[0] + "px"; - this.application.ninja.stage.textTool.element.style.top = textToolCoordinates[1] + "px"; - // Set Width, Height this.application.ninja.stage.textTool.element.style.width = this.selectedElement.offsetWidth + "px"; this.application.ninja.stage.textTool.element.style.height = this.selectedElement.offsetHeight + "px"; @@ -127,18 +135,7 @@ exports.TextTool = Montage.create(DrawingTool, { range.selectNodeContents(this.application.ninja.stage.textTool.element.firstChild); sel.addRange(range); this.didDraw = function() {}; - console.log("im drew here"); } - console.log("i end here"); - } - }, - - - deselectText: { - value: function() { - this.application.ninja.stage.textTool.element.style.display = "none"; - this.selectedElement.innerHTML = this.application.ninja.stage.textTool.value; - this.application.ninja.stage.textTool.value = ""; } }, @@ -162,7 +159,7 @@ exports.TextTool = Montage.create(DrawingTool, { NJevent("enableStageMove"); this.application.ninja.stage.stageDeps.snapManager.setupDragPlaneFromPlane( workingPlane ); } else { - this.deselectText(); + this.selectedElement = null; NJevent("disableStageMove"); } } diff --git a/node_modules/montage/ui/rich-text-editor.reel/shortcut-manager.js b/node_modules/montage/ui/rich-text-editor.reel/shortcut-manager.js new file mode 100644 index 00000000..dac1b638 --- /dev/null +++ b/node_modules/montage/ui/rich-text-editor.reel/shortcut-manager.js @@ -0,0 +1,237 @@ +/* + This file contains proprietary software owned by Motorola Mobility, Inc.
+ No rights, expressed or implied, whatsoever to this software are provided by Motorola Mobility, Inc. hereunder.
+ (c) Copyright 2011 Motorola Mobility, Inc. All Rights Reserved. +
*/ +/** + @module "montage/ui/rich-text-sanitizer.js" + @requires montage/core/core +*/ +var Montage = require("montage").Montage, + Component = require("ui/component").Component + +/** + @class module:"montage/ui/shortcut-manager.js".ShortcutManager +*/ +exports.ShortcutManager = Montage.create(Montage,/** @lends module:"montage/ui/shortcut-manager.js".ShortcutManager# */ { + + /** + Description TODO + @private + */ + _keydownListenerRegistered: { + enumerable: false, + value: false, + distinct: true + }, + + /** + Description TODO + @private + */ + _modifiersMap: { + enumerable: false, + value: null + }, + + /** + Description TODO + @private + */ + _keyNames: { + enumerable: false, + value: { + "BACKSPACE": 8, + "TAB": 9, + "ENTER": 13, + "ESCAPE": 27, + "PAGEUP": 33, + "PAGEDOWN": 34, + "END": 35, + "HOME": 36, + "LEFT": 37, + "UP": 38, + "RIGHT": 39, + "DOWN": 40, + "INSERT": 45, + "DELETE": 46 + // TODO: Complete list... + } + }, + + /** + Description TODO + @private + */ + _shortcutMap: { + enumerable: false, + value: {}, + distinct: true + }, + + /** + Description TODO + @private + */ + _target: { + enumerable: false, + value: null + }, + + /** + Description TODO + Use the shortcuts array to pre-define shortcuts in template, each shortcut is an object with a keys and action property + @private + */ + target: { + enumerable: true, + set: function(target) { + this._target = target; + } + }, + + /** + Description TODO + Use the shortcuts array to pre-define shortcuts in template, each shortcut is an object with a keys and action property + @private + */ + shortcuts: { + enumerable: true, + value: [], + distinct: true + }, + + /** + Description TODO + @type {Function} + */ + deserializedFromTemplate: { + enumerable: false, + value : function() { + var shortcuts = this.shortcuts, + nbrShortcuts = shortcuts.length, + shortcut, + i; + + for (i = 0; i < nbrShortcuts; i ++) { + shortcut = shortcuts[i]; + this.addShortcut(shortcut.keys, shortcut.action); + } + } + }, + + /** + Description TODO + @type {Function} + */ + addShortcut: { + enumerable: true, + value: function(keys, action) { + var target = this._target, + modifiersMap = this._modifiersMap, + shortcutMap = this._shortcutMap, + key, + nbrKeys, + modifiers = 0, + i; + // Make sure we have a valid target + if (!target || (typeof target != "object" || !target.element) && target != "document" && target != document) { + console.log("SHORTCUT MANAGER: You need to set a valid target (must be a component with an element) before you can register shortcut"); + return; + } + + // Initialize the modifiers map if needed + if (!modifiersMap) { + modifiersMap = {SHIFT: 1, CTRL: 2, ALT: 4, META: 8}; + modifiersMap.CMD = window.navigator.userAgent.match(/\bmacintosh\b/i) ? modifiersMap.META : modifiersMap.CTRL; + this._modifiersMap = modifiersMap; + } + + // Register keydown listener + if (!this._keydownListenerRegistered) { + if (target == "document" || target == document) { + document.addEventListener("keydown", this); + } else { + target.element.addEventListener("keydown", this); + } + this._keydownListenerRegistered = true; + } + + // Convert the keys into a modifiers mask + keys = keys.split("+"); + nbrKeys = keys.length; + for (i = 0; i < nbrKeys - 1; i ++) { + modifier = keys[i].toUpperCase(); + if (this._modifiersMap[modifier]) { + modifiers += this._modifiersMap[modifier]; + } + } + + // Extra the final key + key = keys[nbrKeys - 1].toUpperCase(); + if (this._keyNames[key] !== undefined) { + key = this._keyNames[key]; + } else { + key = key.charCodeAt(0); + } + + // Update the shortcutMap + if (shortcutMap[modifiers] === undefined) { + shortcutMap[modifiers] = {}; + } + if (shortcutMap[modifiers][key] === undefined) { + shortcutMap[modifiers][key] = [action]; + } else { + shortcutMap[modifiers][key].push(action); + } + } + }, + + /** + Description TODO + @type {Function} + */ + removeShortcut: { + enumerable: true, + value : function() { + // TODO: Write Me + } + }, + + /** + Description TODO + @function + */ + handleKeydown: { + enumerable: false, + value: function(event) { + var keyCode = event.keyCode, + shortcutMap = this._shortcutMap; + modifiers = event.shiftKey + (event.ctrlKey << 1) + (event.altKey << 2) + (event.metaKey << 3), + stopEvent = false; + + // Check the shortcut map + if (this._shortcutMap[modifiers] && this._shortcutMap[modifiers][keyCode]) { + var handler = this.handler || this._target, + actions = this._shortcutMap[modifiers][keyCode], + nbrActions = actions.length, + action, + i; + + // execute shortcut's action + for (i = 0; i < nbrActions; i ++) { + action = actions[i]; + if (handler && typeof handler.handleShortcut == "function" && handler.handleShortcut(event, action)) { + stopEvent = true; + break; + } + } + } + + if (stopEvent) { + event.preventDefault(); + event.stopPropagation(); + } + } + } +}) \ No newline at end of file -- cgit v1.2.3