Cut/Copy/Paste
svn path=/trunk/aspeditor/; revision=50456
This commit is contained in:
Родитель
f8f7d3e458
Коммит
6be21e54d0
|
@ -0,0 +1,124 @@
|
|||
/*
|
||||
* clipboard.js - methods for manipulating the clipboard
|
||||
*
|
||||
* Authors:
|
||||
* Blagovest Dachev <blago@dachev.com>
|
||||
*
|
||||
* Copyright (C) 2005 Blagovest Dachev
|
||||
*
|
||||
* This sourcecode is licenced under The MIT License:
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to permit
|
||||
* persons to whom the Software is furnished to do so, subject to the
|
||||
* following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
||||
* NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||||
* USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
|
||||
function clipboard(){
|
||||
|
||||
/* ********************************************************************
|
||||
/ PRIVATE VARIABLES AND FUNCTIONS
|
||||
/ only priveleged methdos may view/edit/invoke
|
||||
**********************************************************************/
|
||||
|
||||
|
||||
|
||||
/* ********************************************************************
|
||||
/ PRIVILEGED METHODS
|
||||
/ may be invoked and may access private items
|
||||
/ may not be changed; may be replaced with public flavors
|
||||
**********************************************************************/
|
||||
|
||||
|
||||
/* ********************************************************************
|
||||
/ PUBLIC PROPERTIES
|
||||
/ anyone may read/write
|
||||
**********************************************************************/
|
||||
}
|
||||
|
||||
/* ****************************************************************************
|
||||
/ PUBLIC METHODS
|
||||
/ anyone may read/write
|
||||
******************************************************************************/
|
||||
clipboard.prototype.setClipboard = function(aNewContent)
|
||||
{
|
||||
try {
|
||||
var str = Components.classes ['@mozilla.org/supports-string;1'].
|
||||
createInstance (Components.interfaces.nsISupportsString);
|
||||
str.data = aNewContent;
|
||||
|
||||
var trans = Components.classes ['@mozilla.org/widget/transferable;1'].
|
||||
createInstance (Components.interfaces.nsITransferable);
|
||||
trans.addDataFlavor (TEXT_HTML);
|
||||
trans.addDataFlavor (TEXT_UNICODE);
|
||||
trans.setTransferData (TEXT_HTML, str, aNewContent.length * 2);
|
||||
// TODO: extract only actual text and get rid of all html
|
||||
trans.setTransferData (TEXT_UNICODE, str, aNewContent.length * 2);
|
||||
|
||||
var clipid = Components.interfaces.nsIClipboard;
|
||||
var clip = Components.classes ['@mozilla.org/widget/clipboard;1'].
|
||||
getService (clipid);
|
||||
clip.setData (trans, null, clipid.kGlobalClipboard);
|
||||
} catch (e) {dump (e)}
|
||||
}
|
||||
|
||||
clipboard.prototype.getClipboard = function()
|
||||
{
|
||||
try {
|
||||
var clip = Components.classes ['@mozilla.org/widget/clipboard;1'].
|
||||
getService (Components.interfaces.nsIClipboard);
|
||||
if (!clip)
|
||||
return false;
|
||||
|
||||
var trans = Components.classes ['@mozilla.org/widget/transferable;1'].
|
||||
createInstance (Components.interfaces.nsITransferable);
|
||||
if (!trans)
|
||||
return false;
|
||||
|
||||
trans.addDataFlavor (TEXT_HTML);
|
||||
trans.addDataFlavor (TEXT_UNICODE);
|
||||
|
||||
clip.getData (trans, clip.kGlobalClipboard);
|
||||
|
||||
var dataObj = new Object();
|
||||
var bestFlavor = new Object();
|
||||
var len = new Object();
|
||||
trans.getAnyTransferData (bestFlavor, dataObj, len);
|
||||
if (bestFlavor.value == TEXT_HTML ||
|
||||
bestFlavor.value == TEXT_UNICODE) {
|
||||
if ( dataObj )
|
||||
dataObj = dataObj.value.
|
||||
QueryInterface (Components.interfaces.nsISupportsString);
|
||||
if ( dataObj ) {
|
||||
var id = dataObj.data.substring (0, len.value / 2);
|
||||
}
|
||||
}
|
||||
return id;
|
||||
} catch (e) {dump (e)}
|
||||
}
|
||||
|
||||
/* ****************************************************************************
|
||||
/ PROTOTYOPE PROERTIES
|
||||
/ anyone may read/write (but may be overridden)
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
/* ****************************************************************************
|
||||
/ STATIC PROPERTIES
|
||||
/ anyone may read/write
|
||||
******************************************************************************/
|
|
@ -0,0 +1,76 @@
|
|||
/*
|
||||
* constants.js - Global application constants
|
||||
*
|
||||
* Authors:
|
||||
* Blagovest Dachev <blago@dachev.com>
|
||||
*
|
||||
* Copyright (C) 2005 Blagovest Dachev
|
||||
*
|
||||
* This sourcecode is licenced under The MIT License:
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to permit
|
||||
* persons to whom the Software is furnished to do so, subject to the
|
||||
* following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
||||
* NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||||
* USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
|
||||
const DEBUG = true;
|
||||
const ID = 'id';
|
||||
const WIDTH = 'width';
|
||||
const HEIGHT = 'height';
|
||||
const MIN_WIDTH = 'min-width';
|
||||
const MIN_HEIGHT = 'min-height';
|
||||
const DISPLAY = 'display';
|
||||
const BORDER = 'border';
|
||||
const VERTICAL_ALIGN = 'vertical-align';
|
||||
const POSITION = 'position';
|
||||
const Z_INDEX = 'z-index';
|
||||
const BORDER_CAN_DROP_COLOR = '#ee0000';
|
||||
const BORDER_CAN_DROP_THICK = '2';
|
||||
const BORDER_CAN_DROP_INVERT = false;
|
||||
const DIRECTIVE_PLACE_HOLDER_EXP = /(<directiveplaceholder.[^(><.)]+\/>)/g;
|
||||
const SCRIPT_PLACE_HOLDER_EXP = /(<scriptblockplaceholder.[^(><.)]+\/>)/g;
|
||||
const STRIP_SCRIPT_PLACE_HOLDER_EXP = /<!(?:--(<scriptblockplaceholder[\s\S]*?)--\s*)?>\s*/g;
|
||||
const CONTROL_TAG_NAME = 'aspcontrol';
|
||||
const TABLE = 'table';
|
||||
const EMPTY_CONTROL_EXP = /(<aspcontrol.[^(><.)]+><\/aspcontrol>)/g;
|
||||
const CONTROL_ID_EXP = /(<aspcontrol[\s\S]*?id=")([\D]*?)([\d]*?)(")/g;
|
||||
const BEGIN_CONTROL_TAG_EXP = /(<aspcontrol.[^(><.)]+>)/g;
|
||||
const END_CONTROL_TAG_EXP = /<\/aspcontrol>/g;
|
||||
const STRIP_CONTROL_EXP = /(<span class="ballast".*?><span.*?><div>.*?[\s\S]*?.*?<\/div><\/span><\/span>)/g;
|
||||
const APPEND_TO_CONTROL_END = '</span></span>';
|
||||
const APPEND_TO_CONTROL_BEGIN = "<span class=\"ballast\" style=\"display: block; position: relative\"><span style=\"position: absolute; display: block; z-index: -1;\">";
|
||||
const EMPTY_CONTROL_MSG = '<span style=\"color: #bb0000;\">This control has no HTML<br/>representation associated.</span>';
|
||||
const SINGLE_CLICK = 'single';
|
||||
const DOUBLE_CLICK = 'double';
|
||||
const RIGHT_CLICK = 'right';
|
||||
const OBJECT_RESIZER = Components.interfaces.nsIHTMLObjectResizer;
|
||||
const INLINE_TABLE_EDITOR = Components.interfaces.nsIHTMLInlineTableEditor;
|
||||
const TABLE_EDITOR = Components.interfaces.nsITableEditor;
|
||||
const EDITOR = Components.interfaces.nsIEditor;
|
||||
const SELECTION_PRIVATE = Components.interfaces.nsISelectionPrivate;
|
||||
const STYLE_SHEETS = Components.interfaces.nsIEditorStyleSheets;
|
||||
const EDITOR_CONTENT_STYLE = 'chrome://aspdesigner/content/editorContent.css';
|
||||
const OBJECT = 'object';
|
||||
const CUT = 'cmd_cut';
|
||||
const COPY = 'cmd_copy';
|
||||
const PASTE = 'cmd_paste';
|
||||
const UNDO = 'cmd_undo';
|
||||
const REDO = 'cmd_redo';
|
||||
const TEXT_HTML = 'text/html';
|
||||
const TEXT_UNICODE = 'text/unicode';
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* aspdesigner.js - The asp editor object
|
||||
* editor.js - The asp editor object
|
||||
*
|
||||
* Authors:
|
||||
* Blagovest Dachev <blago@dachev.com>
|
||||
|
@ -30,371 +30,10 @@
|
|||
|
||||
var editor = null;
|
||||
var host = null;
|
||||
var gCancelClick = false;
|
||||
var gDirectivePlaceholder = '';
|
||||
|
||||
const DEBUG = true;
|
||||
const ID = 'id';
|
||||
const WIDTH = 'width';
|
||||
const HEIGHT = 'height';
|
||||
const MIN_WIDTH = 'min-width';
|
||||
const MIN_HEIGHT = 'min-height';
|
||||
const DISPLAY = 'display';
|
||||
const BORDER = 'border';
|
||||
const VERTICAL_ALIGN = 'vertical-align';
|
||||
const POSITION = 'position';
|
||||
const Z_INDEX = 'z-index';
|
||||
const BORDER_CAN_DROP_COLOR = '#ee0000';
|
||||
const BORDER_CAN_DROP_THICK = '2';
|
||||
const BORDER_CAN_DROP_INVERT = false;
|
||||
const DIRECTIVE_PLACE_HOLDER_EXP = /(<directiveplaceholder.[^(><.)]+\/>)/g;
|
||||
const SCRIPT_PLACE_HOLDER_EXP = /(<scriptblockplaceholder.[^(><.)]+\/>)/g;
|
||||
const STRIP_SCRIPT_PLACE_HOLDER_EXP = /<!(?:--(<scriptblockplaceholder[\s\S]*?)--\s*)?>\s*/g;
|
||||
const CONTROL_TAG_NAME = 'aspcontrol';
|
||||
const BEGIN_CONTROL_TAG_EXP = /(<aspcontrol.[^(><.)]+>)/g;
|
||||
const END_CONTROL_TAG_EXP = /<\/aspcontrol>/g;
|
||||
const STRIP_CONTROL_EXP = /(<span class="ballast".*?><span.*?><div>.*?[\s\S]*?.*?<\/div><\/span><\/span>)/g;
|
||||
const APPEND_TO_CONTROL_END = '</div></span></span>';
|
||||
const APPEND_TO_CONTROL_BEGIN = "<span class=\"ballast\" style=\"display: block; position: relative\"><span style=\"position: absolute; display: block; z-index: -1;\"><div>";
|
||||
const EMPTY_CONTROL_MSG = '<span style=\"color: #bb0000;\">This control has no HTML<br>representation associated.</span>';
|
||||
const SINGLE_CLICK = 'single';
|
||||
const DOUBLE_CLICK = 'double';
|
||||
const RIGHT_CLICK = 'right';
|
||||
const OBJECT_RESIZER = Components.interfaces.nsIHTMLObjectResizer;
|
||||
const INLINE_TABLE_EDITOR = Components.interfaces.nsIHTMLInlineTableEditor;
|
||||
const TABLE_EDITOR = Components.interfaces.nsITableEditor;
|
||||
const EDITOR = Components.interfaces.nsIEditor;
|
||||
const SELECTION_PRIVATE = Components.interfaces.nsISelectionPrivate;
|
||||
const STYLE_SHEETS = Components.interfaces.nsIEditorStyleSheets;
|
||||
const EDITOR_CONTENT_STYLE = 'chrome://aspdesigner/content/editorContent.css';
|
||||
const OBJECT = 'object';
|
||||
const CUT = 'cmd_cut';
|
||||
const COPY = 'cmd_copy';
|
||||
const PASTE = 'cmd_paste';
|
||||
const UNDO = 'cmd_undo';
|
||||
const REDO = 'cmd_redo';
|
||||
|
||||
|
||||
//* ___________________________________________________________________________
|
||||
// Implementations of some XPCOM interfaces, to observe various editor events
|
||||
// and actions. Do not remove any of the methods entirely or Mozilla will choke
|
||||
//_____________________________________________________________________________
|
||||
// nsIObserver implementation
|
||||
var gNsIObserverImplementation = {
|
||||
// Tel the host command status has changed.
|
||||
observe: function (aSubject, aTopic, aData)
|
||||
{
|
||||
switch (aTopic) {
|
||||
case 'cmd_bold':
|
||||
break;
|
||||
case 'cmd_italics':
|
||||
break;
|
||||
case 'cmd_underline':
|
||||
break;
|
||||
case 'cmd_indent':
|
||||
break;
|
||||
case 'cmd_outdent':
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// nsISelectionListener implementation
|
||||
// TODO: Redo this one, accounting for recursive calls
|
||||
var gNsISelectionListenerImplementation = {
|
||||
notifySelectionChanged: function(doc, sel, reason)
|
||||
{
|
||||
// Make sure we can't focus a control
|
||||
//TODO: make it account for md-can-drop="true" controls, which
|
||||
// should be able to recieve focus
|
||||
if(sel.isCollapsed) {
|
||||
var focusNode = sel.focusNode;
|
||||
var parentControl =
|
||||
editor.base.getElementOrParentByTagName (CONTROL_TAG_NAME,
|
||||
focusNode);
|
||||
if(parentControl) {
|
||||
editor.base.setCaretAfterElement (parentControl);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// nsIEditActionListener implementation
|
||||
var gNsIEditActionListenerImplementation = {
|
||||
DidCreateNode: function(tag, node, parent, position, result)
|
||||
{
|
||||
//alert('did create node');
|
||||
},
|
||||
|
||||
// TODO: Check if deleted node contains a control, not only if it is one
|
||||
DidDeleteNode: function(child, result)
|
||||
{
|
||||
if(!editor.inResize && !editor.dragState &&
|
||||
!editor.inUpdate && !editor.inCommandExec) {
|
||||
var control = editor.removeLastDeletedControl ();
|
||||
if(control) {
|
||||
var deletionStr = 'deleteControl(s):';
|
||||
deletionStr += ' id=' + control + ',';
|
||||
editor.removeFromControlTable (control);
|
||||
host.removeControl (control);
|
||||
dump (deletionStr +
|
||||
' Message source: DidDeleteNode()');
|
||||
dump ('There is/are '
|
||||
+ editor.controlCount()
|
||||
+ ' controls left in the page');
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
// For each element in to-be-deleted array, remove control from the control
|
||||
// table, let the host know we have deleted a control by calling the
|
||||
// respective method, and remove from to-be-deleted array.
|
||||
DidDeleteSelection: function(selection)
|
||||
{
|
||||
if(!editor.inResize && !editor.dragState &&
|
||||
!editor.inUpdate && !editor.inCommandExec) {
|
||||
var control = editor.removeLastDeletedControl ();
|
||||
if(control) {
|
||||
var deletionStr = 'Did delete control(s):';
|
||||
while(control) {
|
||||
deletionStr += ' id=' + control + ',';
|
||||
editor.removeFromControlTable (control);
|
||||
host.removeControl (control);
|
||||
control = editor.removeLastDeletedControl ();
|
||||
}
|
||||
dump (deletionStr +
|
||||
' Message source: DidDeleteSelection()');
|
||||
dump ('There is/are ' +
|
||||
editor.controlCount() +
|
||||
' controls left in the page');
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
DidDeleteText: function(textNode, offset, length, result)
|
||||
{
|
||||
|
||||
},
|
||||
|
||||
// Make sure to check node contents for controls too. The node could be
|
||||
// a table (or any other element) with a control inside.
|
||||
DidInsertNode: function(node, parent, position, result)
|
||||
{
|
||||
var dumpStr = 'Did insert node ' + node.nodeName;
|
||||
dumpStr += (node.nodeType == 1) ?
|
||||
', id=' + node.getAttribute(ID) :
|
||||
'';
|
||||
dump (dumpStr);
|
||||
|
||||
// Check to see if we have inserted a new controls. We need to
|
||||
// add'em to the control table. Also update reference to all
|
||||
// existing controls
|
||||
var controls =
|
||||
editor.base.document.getElementsByTagName (CONTROL_TAG_NAME);
|
||||
if(controls.length > 0) {
|
||||
var i = 0;
|
||||
var width, height;
|
||||
while(controls [i]) {
|
||||
if(editor.getControlTable ().getById (controls [i].getAttribute (ID))) {
|
||||
editor.getControlTable ().update (controls [i].getAttribute (ID),
|
||||
controls [i]);
|
||||
dump ('Did update control(id=' +
|
||||
controls [i].getAttribute (ID) +
|
||||
') reference in table');
|
||||
}
|
||||
else {
|
||||
editor.insertInControlTable (controls [i].getAttribute (ID),
|
||||
controls [i]);
|
||||
dump ('New control (id=' +
|
||||
controls [i].getAttribute (ID) +
|
||||
') inserted');
|
||||
dump ('There is/are ' +
|
||||
editor.controlCount() +
|
||||
' controls in the page');
|
||||
}
|
||||
editor.setSelectNone (controls [i]);
|
||||
width = controls [i].getAttribute(WIDTH);
|
||||
height = controls [i].getAttribute(HEIGHT);
|
||||
controls [i].style.setProperty (MIN_WIDTH,
|
||||
width, '');
|
||||
controls [i].style.setProperty (MIN_HEIGHT,
|
||||
height, '');
|
||||
controls [i].style.setProperty (DISPLAY,
|
||||
'-moz-inline-box', '');
|
||||
controls [i].style.setProperty (BORDER,
|
||||
'1px solid #ff0000', '');
|
||||
controls [i].style.setProperty (VERTICAL_ALIGN,
|
||||
'text-bottom', '');
|
||||
controls [i].style.setProperty (POSITION,
|
||||
'relative', '');
|
||||
controls [i].style.setProperty (Z_INDEX,
|
||||
'1', '');
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
if(editor.dragState) {
|
||||
dump ('End drag');
|
||||
}
|
||||
|
||||
if(editor.nodeIsControl (node) &&
|
||||
(node.nodeType == 1 || node.nodeType == 3)) {
|
||||
//editor.selectControl (node.getAttribute (ID));
|
||||
}
|
||||
if(editor.dragState)
|
||||
editor.dragState = false;
|
||||
},
|
||||
|
||||
DidInsertText: function(textNode, offset, string, result)
|
||||
{
|
||||
|
||||
},
|
||||
|
||||
DidJoinNodes: function(leftNode, rightNode, parent, result)
|
||||
{
|
||||
//alert('did join nodes');
|
||||
},
|
||||
|
||||
DidSplitNode: function(existingRightNode, offset, newLeftNode, result)
|
||||
{
|
||||
//alert('did split node');
|
||||
},
|
||||
|
||||
WillCreateNode: function(tag, parent, position)
|
||||
{
|
||||
//alert ('Will create node');
|
||||
},
|
||||
|
||||
WillDeleteNode: function(child)
|
||||
{
|
||||
dump ('will delete node-----------------------');
|
||||
if(!editor.inResize && !editor.dragState &&
|
||||
!editor.inUpdate && !editor.inCommandExec) {
|
||||
var deletionStr = 'Will delete control(s):';
|
||||
var i = 0;
|
||||
|
||||
// is the node itself control?
|
||||
if(editor.nodeIsControl (child)) {
|
||||
deletionStr += ' id=' +
|
||||
child.getAttribute (ID) + ',';
|
||||
editor.addLastDeletedControl (child.getAttribute (ID));
|
||||
}
|
||||
|
||||
// does the node contain any controls?
|
||||
var control = editor.getControlFromTableByIndex (i);
|
||||
while(control) {
|
||||
if(editor.isControlChildOf (child, control)) {
|
||||
deletionStr += ' id=' +
|
||||
control.getAttribute (ID) + ',';
|
||||
editor.addLastDeletedControl (control.getAttribute (ID));
|
||||
}
|
||||
i++;
|
||||
control = editor.getControlFromTableByIndex (i);
|
||||
}
|
||||
if(deletionStr != 'Will delete control(s):')
|
||||
dump (deletionStr +
|
||||
' Message source: WillDeleteNode()');
|
||||
}
|
||||
},
|
||||
|
||||
// Check if the selection to be deleted contains controls and prepare
|
||||
//for deletion. Load all to-be-deleted controls in an array, so we can
|
||||
// access them after actual deletion in order to notify the host.
|
||||
WillDeleteSelection: function(selection)
|
||||
{
|
||||
dump ('will delete selection-----------------------');
|
||||
if(!editor.inResize && !editor.dragState &&
|
||||
!editor.inUpdate && !editor.inCommandExec) {
|
||||
var i = 0;
|
||||
var control = editor.getControlFromTableByIndex (i);
|
||||
var deletionStr = 'Will delete control(s):';
|
||||
if(control) {
|
||||
while(control) {
|
||||
if(selection.containsNode (control, true)) {
|
||||
deletionStr += ' id=' +
|
||||
control.getAttribute (ID) + ',';
|
||||
editor.addLastDeletedControl (control.getAttribute (ID));
|
||||
}
|
||||
i++;
|
||||
control = editor.getControlFromTableByIndex (i);
|
||||
}
|
||||
if(deletionStr != 'Will delete control(s):')
|
||||
dump (deletionStr +
|
||||
' Message source: WillDeleteSelection()');
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
WillDeleteText: function(textNode, offset, length)
|
||||
{
|
||||
|
||||
},
|
||||
|
||||
WillInsertNode: function(node, parent, position)
|
||||
{
|
||||
|
||||
},
|
||||
|
||||
WillInsertText: function(textNode, offset, string)
|
||||
{
|
||||
|
||||
},
|
||||
|
||||
WillJoinNodes: function(leftNode, rightNode, parent)
|
||||
{
|
||||
//alert ('Will join node');
|
||||
},
|
||||
|
||||
WillSplitNode: function(existingRightNode, offset)
|
||||
{
|
||||
//alert ('Will split node');
|
||||
},
|
||||
}
|
||||
|
||||
// nsIHTMLObjectResizeListener implementation
|
||||
var gNsIHTMLObjectResizeListenerImplementation = {
|
||||
onEndResizing: function(element, oldWidth, oldHeight, newWidth, newHeight)
|
||||
{
|
||||
if(editor.nodeIsControl (element)) {
|
||||
var id = element.getAttribute (ID);
|
||||
host.resizeControl (id, newWidth, newHeight);
|
||||
}
|
||||
editor.inResize = false;
|
||||
dump ('End resize.');
|
||||
},
|
||||
|
||||
onStartResizing: function(element)
|
||||
{
|
||||
if(editor.nodeIsControl (element)) {
|
||||
editor.beginBatch ();
|
||||
}
|
||||
editor.inResize = true;
|
||||
dump ('Begin resize.');
|
||||
}
|
||||
}
|
||||
|
||||
// nsIContentFilter implementation
|
||||
// In future we should use this one to manage all insertion coming from
|
||||
// paste, drag&drop, insertHTML(), and page load. Currently not working.
|
||||
// Mozilla throws an INVALID_POINTER exception
|
||||
var gNsIContentFilterImplementation = {
|
||||
notifyOfInsertion: function(mimeType,
|
||||
contentSourceURL,
|
||||
sourceDocument,
|
||||
willDeleteSelection,
|
||||
docFragment,
|
||||
contentStartNode,
|
||||
contentStartOffset,
|
||||
contentEndNode,
|
||||
contentEndOffset,
|
||||
insertionPointNode,
|
||||
insertionPointOffset,
|
||||
continueWithInsertion)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
//* ___________________________________________________________________________
|
||||
// This class is responsible for communication with the host system and
|
||||
// implements part of the AspNetDesigner interface
|
||||
|
@ -406,6 +45,9 @@ function aspNetHost()
|
|||
}
|
||||
aspNetHost.prototype =
|
||||
{
|
||||
mSerializedContent : '',
|
||||
mDeserializedContent : '',
|
||||
|
||||
initialize: function()
|
||||
{
|
||||
// Register our interface methods with the host
|
||||
|
@ -421,9 +63,17 @@ aspNetHost.prototype =
|
|||
// Control selection
|
||||
JSCallRegisterClrHandler ('SelectControl', JSCall_SelectControl);
|
||||
// HTML editing
|
||||
JSCallRegisterClrHandler ('DoCommand', JSCall_DoCommand);
|
||||
JSCallRegisterClrHandler ('IsCommandEnabled', JSCall_IsCommandEnabled);
|
||||
JSCallRegisterClrHandler ('InsertFragment', JSCall_InsertFragment);
|
||||
JSCallRegisterClrHandler ('DoCommand',
|
||||
JSCall_DoCommand);
|
||||
JSCallRegisterClrHandler ('IsCommandEnabled',
|
||||
JSCall_IsCommandEnabled);
|
||||
JSCallRegisterClrHandler ('InsertFragment',
|
||||
JSCall_InsertFragment);
|
||||
// Misc
|
||||
JSCallRegisterClrHandler ('SerializeReturn',
|
||||
JSCall_SerializeReturn);
|
||||
JSCallRegisterClrHandler ('DeserializeAndAddReturn',
|
||||
JSCall_DeserializeAndAddReturn);
|
||||
|
||||
//tell the host we're ready for business
|
||||
JSCallPlaceClrCall ('Activate', '', '');
|
||||
|
@ -444,10 +94,12 @@ aspNetHost.prototype =
|
|||
}
|
||||
|
||||
if(!aControlId) {
|
||||
dump (clickType + ' click over no control; deselecting all controls');
|
||||
dump (clickType +
|
||||
' click over no control; deselecting all controls');
|
||||
}
|
||||
else {
|
||||
dump (clickType + " click over aspcontrol \"" + aControlId + "\"");
|
||||
dump (clickType + " click over aspcontrol \"" +
|
||||
aControlId + "\"");
|
||||
}
|
||||
|
||||
JSCallPlaceClrCall ('Click', '', new Array(clickType, aControlId));
|
||||
|
@ -456,20 +108,62 @@ aspNetHost.prototype =
|
|||
|
||||
resizeControl: function(aControlId, aWidth, aHeight)
|
||||
{
|
||||
JSCallPlaceClrCall ('ResizeControl', '', new Array(aControlId, aWidth, aHeight));
|
||||
dump ('Outbound call to ResizeControl() id=' + aControlId +
|
||||
', new size ' + aWidth + 'x' + aHeight);
|
||||
},
|
||||
|
||||
throwException: function (location, msg)
|
||||
{
|
||||
JSCallPlaceClrCall ('ThrowException', '', new Array(location, msg));
|
||||
JSCallPlaceClrCall ('ResizeControl', '',
|
||||
new Array(aControlId, aWidth, aHeight));
|
||||
},
|
||||
|
||||
removeControl: function (aControlId)
|
||||
{
|
||||
JSCallPlaceClrCall ('RemoveControl', '', new Array(aControlId));
|
||||
dump ('Outbound call to removeControl() id=' + aControlId);
|
||||
JSCallPlaceClrCall ('RemoveControl', '', new Array(aControlId));
|
||||
},
|
||||
|
||||
serialize: function (aClipboardContent, aReturn)
|
||||
{
|
||||
// On first invocation we call the host. It then returns to
|
||||
// SerializeReturn which in turn invokes this method again
|
||||
// and sets the member var with the new clipboard content
|
||||
// ("else" block). First-invocation execution picks up after
|
||||
// the host call, and we are able to return the new content
|
||||
// (mSerializedContent) to the caller.
|
||||
if (!aReturn) {
|
||||
dump ('Outbound call to Serialize() content=' +
|
||||
aClipboardContent);
|
||||
JSCallPlaceClrCall ('Serialize', 'SerializeReturn',
|
||||
new Array(aClipboardContent));
|
||||
return this.mSerializedContent;
|
||||
}
|
||||
else {
|
||||
this.mSerializedContent = aClipboardContent;
|
||||
}
|
||||
},
|
||||
|
||||
deserializeAndAdd: function (aClipboardContent, aReturn)
|
||||
{
|
||||
// On first invocation we call the host. It then returns to
|
||||
// SerializeReturn which in turn invokes this method again
|
||||
// and sets the member var with the new clipboard content
|
||||
// ("else" block). First-invocation execution picks up after
|
||||
// the host call, and we are able to return the new content
|
||||
// (mDeserializedContent) to the caller.
|
||||
if (!aReturn) {
|
||||
dump ('Outbound call to DeserializeAndAdd() content=' +
|
||||
aClipboardContent);
|
||||
JSCallPlaceClrCall ('DeserializeAndAdd',
|
||||
'DeserializeAndAddReturn',
|
||||
new Array(aClipboardContent));
|
||||
return this.mDeserializedContent;
|
||||
}
|
||||
else {
|
||||
this.mDeserializedContent = aClipboardContent;
|
||||
}
|
||||
},
|
||||
|
||||
throwException: function (location, msg)
|
||||
{
|
||||
JSCallPlaceClrCall ('ThrowException', '', new Array(location, msg));
|
||||
},
|
||||
}
|
||||
|
||||
|
@ -529,6 +223,14 @@ function JSCall_InsertFragment (arg) {
|
|||
return editor.insertFragment (arg [0]);
|
||||
}
|
||||
|
||||
function JSCall_SerializeReturn (arg) {
|
||||
host.serialize (arg [0], true);
|
||||
}
|
||||
|
||||
function JSCall_DeserializeAndAddReturn (arg) {
|
||||
host.deserializeAndAdd (arg [0], true);
|
||||
}
|
||||
|
||||
//* ___________________________________________________________________________
|
||||
// A rather strange data structure to store current controls in the page.
|
||||
// Insertion is O(1), removal is O(n), memory usage is O(2n), but query by
|
||||
|
@ -605,7 +307,6 @@ var controlTable = {
|
|||
function aspNetEditor_initialize()
|
||||
{
|
||||
dump ("Initialising...");
|
||||
dump ("\tCreating host...");
|
||||
editor = new aspNetEditor ();
|
||||
dump ("\tCreated editor, initialising...");
|
||||
editor.initialize ();
|
||||
|
@ -613,6 +314,9 @@ function aspNetEditor_initialize()
|
|||
host = new aspNetHost ();
|
||||
dump ("\tHost created, initialising...");
|
||||
host.initialize ();
|
||||
dump ("\tHost initialised, creating clipboard...");
|
||||
clip = new clipboard ();
|
||||
dump ("\tClipboard created.");
|
||||
dump ("Initialised.");
|
||||
}
|
||||
|
||||
|
@ -623,33 +327,37 @@ function aspNetEditor()
|
|||
|
||||
aspNetEditor.prototype =
|
||||
{
|
||||
mNsIHtmlEditor : null,
|
||||
mNsIEditor : null,
|
||||
mNsIHtmlObjectResizer : null,
|
||||
mNsIHTMLInlineTableEditor : null,
|
||||
mNsIEditorStyleSheets : null,
|
||||
mNsICommandManager : null,
|
||||
mNsIHtmlEditor : null,
|
||||
mNsIEditor : null,
|
||||
mNsIHtmlObjectResizer : null,
|
||||
mNsIHTMLInlineTableEditor : null,
|
||||
mNsIEditorStyleSheets : null,
|
||||
mNsICommandManager : null,
|
||||
|
||||
mEditorWindow : null,
|
||||
mDropInElement : null,
|
||||
mControlTable : null,
|
||||
mLastDeletedControls : null,
|
||||
mLastSelectedControls : null,
|
||||
mInResize : false,
|
||||
mInCommandExec : false,
|
||||
mInUpdate : false,
|
||||
mInDrag : false,
|
||||
mEditorElement : null,
|
||||
mEditorWindow : null,
|
||||
mDropInElement : null,
|
||||
mControlTable : null,
|
||||
mLastDeletedControls : null,
|
||||
mLastSelectedControls : null,
|
||||
mCancelClick : false,
|
||||
mInResize : false,
|
||||
mInCommandExec : false,
|
||||
mInUpdate : false,
|
||||
mInDrag : false,
|
||||
|
||||
mLastClipboardUpdateCommand : '',
|
||||
|
||||
initialize: function()
|
||||
{
|
||||
var editorElement = document.getElementById ('aspeditor');
|
||||
editorElement.makeEditable ('html', false);
|
||||
this.mEditorElement = document.getElementById ('aspeditor');
|
||||
this.mEditorElement.makeEditable ('html', false);
|
||||
|
||||
this.mEditorWindow = editorElement.contentWindow;
|
||||
this.mEditorWindow = this.mEditorElement.contentWindow;
|
||||
this.mNsIHtmlEditor =
|
||||
editorElement.getHTMLEditor(this.mEditorWindow);
|
||||
this.mEditorElement.getHTMLEditor(this.mEditorWindow);
|
||||
this.mNsICommandManager =
|
||||
editorElement.commandManager;
|
||||
this.mEditorElement.commandManager;
|
||||
this.mNsIEditor =
|
||||
this.mNsIHtmlEditor.QueryInterface(EDITOR);
|
||||
this.mNsIHTMLInlineTableEditor =
|
||||
|
@ -688,8 +396,24 @@ aspNetEditor.prototype =
|
|||
get inCommandExec() { return this.mInCommandExec },
|
||||
set inCommandExec(aBool) { this.mInCommandExec = aBool },
|
||||
|
||||
get base() { return this.mNsIHtmlEditor },
|
||||
get controlCount() { return this.mControlTable.getCount () },
|
||||
get cancelClick() { return this.mCancelClick },
|
||||
set cancelClick(aBool) { this.mCancelClick = aBool },
|
||||
|
||||
get controlCount() { return this.mControlTable.getCount (); },
|
||||
get editorWindow() { return this.mEditorWindow },
|
||||
|
||||
get base()
|
||||
{
|
||||
var editor;
|
||||
try {
|
||||
editor = this.mEditorElement.getEditor (this.mEditorWindow);
|
||||
|
||||
editor instanceof Components.interfaces.nsIPlaintextEditor;
|
||||
editor instanceof Components.interfaces.nsIHTMLEditor;
|
||||
} catch (e) {}
|
||||
|
||||
return editor;
|
||||
},
|
||||
|
||||
beginBatch: function()
|
||||
{
|
||||
|
@ -845,7 +569,7 @@ aspNetEditor.prototype =
|
|||
{
|
||||
// Give controls a default value
|
||||
var emptyControl =
|
||||
aHTML.match(/(<aspcontrol.[^(><.)]+><\/aspcontrol>)/g);
|
||||
aHTML.match(EMPTY_CONTROL_EXP);
|
||||
var controlBegin = "$&" + APPEND_TO_CONTROL_BEGIN;
|
||||
controlBegin = (emptyControl) ?
|
||||
controlBegin + EMPTY_CONTROL_MSG :
|
||||
|
@ -900,6 +624,8 @@ aspNetEditor.prototype =
|
|||
{
|
||||
if(aHtml) {
|
||||
try {
|
||||
this.base.selectAll ();
|
||||
this.base.deleteSelection (1);
|
||||
var html = this.transformBeforeInput(aHtml, true);
|
||||
dump ("Loading page: " + html);
|
||||
this.mNsIHtmlEditor.rebuildDocumentFromSource (html);
|
||||
|
@ -1064,7 +790,8 @@ aspNetEditor.prototype =
|
|||
// TODO: Handle commands on controls independently
|
||||
doCommand: function (aCommand)
|
||||
{
|
||||
this.inCommandExec = true;
|
||||
if(aCommand != CUT)
|
||||
this.inCommandExec = true;
|
||||
if (this.mNsICommandManager.isCommandSupported (aCommand, this.mEditorWindow)) {
|
||||
switch (aCommand) {
|
||||
case 'cmd_bold':
|
||||
|
@ -1093,8 +820,16 @@ aspNetEditor.prototype =
|
|||
this.mEditorWindow);
|
||||
break;
|
||||
case 'cmd_cut':
|
||||
this.mNsICommandManager.doCommand (aCommand,
|
||||
null,
|
||||
this.mEditorWindow);
|
||||
this.mLastClipboardUpdateCommand = CUT;
|
||||
break;
|
||||
case 'cmd_copy':
|
||||
this.mNsICommandManager.doCommand (aCommand,
|
||||
null,
|
||||
this.mEditorWindow);
|
||||
this.mLastClipboardUpdateCommand = COPY;
|
||||
break;
|
||||
case 'cmd_paste':
|
||||
var focusNode = this.base.selection.focusNode;
|
||||
|
@ -1106,8 +841,20 @@ aspNetEditor.prototype =
|
|||
this.selectControl (controlId);
|
||||
}
|
||||
this.collapseBeforeInsertion ("end");
|
||||
if(this.mNsIEditor.canPaste (1))
|
||||
this.mNsIEditor.paste (1);
|
||||
|
||||
// We shouldn't paste directlly since there
|
||||
// might be ASP controls in the clipboard.
|
||||
// Get the design-time HTML with proper, new
|
||||
// control ID's from the host, then paste it
|
||||
// and restore the original clipboard content.
|
||||
var content = clip.getClipboard ();
|
||||
var newContent = host.deserializeAndAdd (content);
|
||||
//clip.setClipboard (newContent);
|
||||
//this.mNsICommandManager.doCommand (PASTE,
|
||||
//null,
|
||||
//this.mEditorWindow);
|
||||
//clip.setClipboard (content);
|
||||
|
||||
break;
|
||||
default:
|
||||
this.mNsICommandManager.doCommand (aCommand,
|
||||
|
@ -1307,6 +1054,26 @@ aspNetEditor.prototype =
|
|||
}
|
||||
return null;
|
||||
},
|
||||
|
||||
clone: function (aObj)
|
||||
{
|
||||
var clone = {};
|
||||
for (var i in aObj) {
|
||||
if(typeof aObj [i] == OBJECT)
|
||||
clone [i] = this.clone (aObj [i]);
|
||||
else
|
||||
clone [i] = aObj [i];
|
||||
}
|
||||
return clone;
|
||||
},
|
||||
|
||||
cancelTableOverrideStyle: function (aTables)
|
||||
{
|
||||
var table;
|
||||
while((table = aTables.nextNode ()) != null) {
|
||||
table.setAttribute ('cancelUI', 'true');
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
//* ___________________________________________________________________________
|
||||
|
@ -1359,11 +1126,20 @@ function handleDragStart(aEvent) {
|
|||
}
|
||||
|
||||
function handleDrop(aEvent) {
|
||||
//Nothing special here for now
|
||||
try {
|
||||
//var tmp = aEvent.
|
||||
//var evt = document.createEvent('UIEvents');
|
||||
//evt.initMouseEvent("dragdrop", true, true, editor.editorWindow,
|
||||
//1, 10, 50, 10, 50, false, false, false, false, 0, editor.base.rootElement);
|
||||
aEvent.stopPropagation ();
|
||||
aEvent.preventDefault ();
|
||||
editor.base.insertFromDrop (aEvent);
|
||||
editor.base.setShouldTxnSetSelection (false);
|
||||
} catch (e) {alert (e)}
|
||||
}
|
||||
|
||||
function handleSingleClick(aButton, aTarget) {
|
||||
if(!gCancelClick) {
|
||||
if(!editor.cancelClick) {
|
||||
control =
|
||||
editor.base.getElementOrParentByTagName (CONTROL_TAG_NAME,
|
||||
aTarget);
|
||||
|
@ -1383,15 +1159,15 @@ function handleSingleClick(aButton, aTarget) {
|
|||
|
||||
function detectSingleClick(aEvent)
|
||||
{
|
||||
gCancelClick = false;
|
||||
editor.cancelClick = false;
|
||||
var button = aEvent.button;
|
||||
var target = aEvent.target;
|
||||
setTimeout (function() { handleSingleClick(button, target); }, 300);
|
||||
setTimeout (function() { handleSingleClick(button, target); }, 100);
|
||||
}
|
||||
|
||||
function detectDoubleClick(aEvent)
|
||||
{
|
||||
gCancelClick = true;
|
||||
editor.cancelClick = true;
|
||||
control = editor.base.getElementOrParentByTagName (CONTROL_TAG_NAME,
|
||||
aEvent.target);
|
||||
var controlId =
|
||||
|
@ -1399,7 +1175,7 @@ function detectDoubleClick(aEvent)
|
|||
|
||||
|
||||
host.click (DOUBLE_CLICK, controlId);
|
||||
//alert (editor.getPage ());
|
||||
alert (editor.getPage ());
|
||||
}
|
||||
|
||||
function handleContextMenu(aEvent)
|
||||
|
@ -1547,8 +1323,26 @@ function handleKeyPress(aEvent) {
|
|||
}
|
||||
}
|
||||
|
||||
function handleClipboardUpdate() {
|
||||
var content = clip.getClipboard ();
|
||||
content = editor.transformBeforeOutput (content, false);
|
||||
|
||||
alert (clip.getClipboard ());
|
||||
var newContent = host.serialize (content);
|
||||
clip.setClipboard (newContent);
|
||||
alert (clip.getClipboard ());
|
||||
}
|
||||
|
||||
// Define a NodeFilter function to accept only <table> elements
|
||||
function tableFilter(aNode) {
|
||||
if (aNode.tagName.toLowerCase () == TABLE)
|
||||
return NodeFilter.FILTER_ACCEPT;
|
||||
else
|
||||
return NodeFilter.FILTER_SKIP;
|
||||
}
|
||||
|
||||
function dump(aTxtAppend) {
|
||||
if(DEBUG) {
|
||||
JSCallPlaceClrCall ('DebugStatement', '', new Array(aTxtAppend));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -6,16 +6,24 @@
|
|||
xmlns = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
xmlns:html = "http://www.w3.org/1999/xhtml"
|
||||
onload = "aspNetEditor_initialize();">
|
||||
|
||||
|
||||
<script type="application/x-javascript" src="chrome://aspdesigner/content/xpcom.js"/>
|
||||
<script type="application/x-javascript" src="chrome://aspdesigner/content/constants.js"/>
|
||||
<script type="application/x-javascript" src="chrome://aspdesigner/content/clipboard.js"/>
|
||||
<script type="application/x-javascript" src="chrome://aspdesigner/content/editor.js"/>
|
||||
<script type="application/x-javascript" src="chrome://aspdesigner/content/JSCall.js"/>
|
||||
|
||||
<hbox flex="4">
|
||||
<vbox flex="15">
|
||||
<editor editortype="html" type="content-primary" id="aspeditor"
|
||||
context="editorContentContext" flex="1" tooltip="aHTMLTooltip"/>
|
||||
context="editorContentContext" flex="1"/>
|
||||
</vbox>
|
||||
</hbox>
|
||||
|
||||
<commandset id="clipboard"
|
||||
commandupdater="true"
|
||||
events="clipboard"
|
||||
oncommandupdate="handleClipboardUpdate ();"/>
|
||||
</window>
|
||||
|
||||
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
/*
|
||||
* editorContent.css - Some styles rules for elements in edit mode
|
||||
* editorContent.css - Some style~="border"s rules for elements in edit mode
|
||||
* Original Code:
|
||||
* Daniel Glazman <glazman@netscape.com>
|
||||
*
|
||||
* Contributor(s):
|
||||
* Authors:
|
||||
* Blagovest Dachev <blago@dachev.com>
|
||||
*
|
||||
* This sourcecode is licenced under The MIT License:
|
||||
|
@ -27,7 +27,6 @@
|
|||
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||||
* USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
@import url(chrome://communicator/skin/smileys.css);
|
||||
|
||||
a[name] {
|
||||
min-height : 17px; margin-left: 2px; margin-top: 2px;
|
||||
|
@ -47,40 +46,26 @@ table {
|
|||
/* give a red dotted border to tables and cells with no border
|
||||
otherwise they are invisible
|
||||
*/
|
||||
table[empty-cells],
|
||||
table[border="0"],
|
||||
table[empty-cells]:not([cancelUI]),
|
||||
table[border="0"]:not([cancelUI]),
|
||||
/* next two selectors on line below for the case where tbody is omitted */
|
||||
table[border="0"] > tr > td, table[border="0"] > tr > th,
|
||||
table[border="0"] > thead > tr > td, table[border="0"] > tbody > tr > td, table[border="0"] > tfoot > tr > td,
|
||||
table[border="0"] > thead > tr > th, table[border="0"] > tbody > tr > th, table[border="0"] > tfoot > tr > th,
|
||||
table:not([border]),
|
||||
table[border="0"]:not([cancelUI]) > tr > td, table[border="0"]:not([cancelUI]) > tr > th,
|
||||
table[border="0"]:not([cancelUI]) > thead > tr > td, table[border="0"]:not([cancelUI]) > tbody > tr > td, table[border="0"]:not([cancelUI]) > tfoot > tr > td,
|
||||
table[border="0"]:not([cancelUI]) > thead > tr > th, table[border="0"]:not([cancelUI]) > tbody > tr > th, table[border="0"]:not([cancelUI]) > tfoot > tr > th,
|
||||
table:not([border]):not([cancelUI]),
|
||||
/* next two selectors on line below for the case where tbody is omitted */
|
||||
table:not([border]) > tr > td, table:not([border]) > tr > th,
|
||||
table:not([border]) > thead > tr > td, table:not([border]) > tbody > tr > td, table:not([border]) > tfoot > tr > td,
|
||||
table:not([border]) > thead > tr > th, table:not([border]) > tbody > tr > th, table:not([border]) > tfoot > tr > th {
|
||||
border : 1px dotted red;
|
||||
}
|
||||
|
||||
/* Cancell the above rules in case the table is in control
|
||||
*/
|
||||
aspcontrol table[empty-cells],
|
||||
aspcontrol table[border="0"],
|
||||
/* next two selectors on line below for the case where tbody is omitted */
|
||||
aspcontrol table[border="0"] > tr > td, aspcontrol table[border="0"] > tr > th,
|
||||
aspcontrol table[border="0"] > thead > tr > td, aspcontrol table[border="0"] > tbody > tr > td, aspcontrol table[border="0"] > tfoot > tr > td,
|
||||
aspcontrol table[border="0"] > thead > tr > th, aspcontrol table[border="0"] > tbody > tr > th, aspcontrol table[border="0"] > tfoot > tr > th,
|
||||
aspcontrol table:not([border]),
|
||||
/* next two selectors on line below for the case where tbody is omitted */
|
||||
aspcontrol table:not([border]) > tr > td, aspcontrol table:not([border]) > tr > th,
|
||||
aspcontrol table:not([border]) > thead > tr > td, aspcontrol table:not([border]) > tbody > tr > td, aspcontrol table:not([border]) > tfoot > tr > td,
|
||||
aspcontrol table:not([border]) > thead > tr > th, aspcontrol table:not([border]) > tbody > tr > th, aspcontrol table:not([border]) > tfoot > tr > th {
|
||||
border : 0;
|
||||
table:not([border]):not([cancelUI]) > tr > td, table:not([border]):not([cancelUI]) > tr > th,
|
||||
table:not([border]):not([cancelUI]) > thead > tr > td, table:not([border]):not([cancelUI]) > tbody > tr > td, table:not([border]):not([cancelUI]) > tfoot > tr > td,
|
||||
table:not([border]):not([cancelUI]) > thead > tr > th, table:not([border]):not([cancelUI]) > tbody > tr > th, table:not([border]):not([cancelUI]) > tfoot > tr > th
|
||||
{
|
||||
border : 1px dotted #d59408;
|
||||
}
|
||||
|
||||
/* give a green dashed border to forms otherwise they are invisible
|
||||
*/
|
||||
form {
|
||||
border : 2px dashed green;
|
||||
border : 2px dashed #9c9d83;
|
||||
min-height : 20px;
|
||||
}
|
||||
/* give a green dotted border to labels otherwise they are invisible
|
||||
*/
|
||||
|
@ -91,12 +76,21 @@ label {
|
|||
img {
|
||||
-moz-force-broken-image-icon: 1;
|
||||
}
|
||||
/* give a green dotted border to labels otherwise they are invisible
|
||||
/* Some <aspcontrol> properties that will persist
|
||||
*/
|
||||
aspcontrol {
|
||||
border : 1px solid #ff0000;
|
||||
border : 1px solid #7f9db9;
|
||||
display : -moz-inline-box;
|
||||
vertical-align : text-bottom;
|
||||
z-index : 1;
|
||||
position : relative;
|
||||
/*-moz-binding : url("chrome://aspdesigner/content/editor.xml#aspcontrol");*/
|
||||
}
|
||||
|
||||
span.onionOne {
|
||||
display: block; position: relative;
|
||||
}
|
||||
|
||||
span.onionTwo {
|
||||
position: absolute; display: block; z-index: -1;
|
||||
}
|
|
@ -0,0 +1,360 @@
|
|||
/*
|
||||
* xpcom.js - Implementations of some XPCOM interfaces
|
||||
*
|
||||
* Authors:
|
||||
* Blagovest Dachev <blago@dachev.com>
|
||||
*
|
||||
* Copyright (C) 2005 Blagovest Dachev
|
||||
*
|
||||
* This sourcecode is licenced under The MIT License:
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to permit
|
||||
* persons to whom the Software is furnished to do so, subject to the
|
||||
* following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
||||
* NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||||
* USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
//* ___________________________________________________________________________
|
||||
// Implementations of some XPCOM interfaces, to observe various editor events
|
||||
// and actions. Do not remove any of the methods entirely or Mozilla will choke
|
||||
//_____________________________________________________________________________
|
||||
// nsIObserver implementation
|
||||
var gNsIObserverImplementation = {
|
||||
// Tel the host command status has changed.
|
||||
observe: function (aSubject, aTopic, aData)
|
||||
{
|
||||
switch (aTopic) {
|
||||
case 'cmd_bold':
|
||||
break;
|
||||
case 'cmd_italics':
|
||||
break;
|
||||
case 'cmd_underline':
|
||||
break;
|
||||
case 'cmd_indent':
|
||||
break;
|
||||
case 'cmd_outdent':
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// nsISelectionListener implementation
|
||||
// TODO: Redo this one, accounting for recursive calls
|
||||
var gNsISelectionListenerImplementation = {
|
||||
notifySelectionChanged: function(doc, sel, reason)
|
||||
{
|
||||
// Make sure we can't focus a control
|
||||
//TODO: make it account for md-can-drop="true" controls, which
|
||||
// should be able to recieve focus
|
||||
if(sel.isCollapsed) {
|
||||
var focusNode = sel.focusNode;
|
||||
var parentControl =
|
||||
editor.base.getElementOrParentByTagName (CONTROL_TAG_NAME,
|
||||
focusNode);
|
||||
if(parentControl) {
|
||||
editor.base.setCaretAfterElement (parentControl);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// nsIEditActionListener implementation
|
||||
var gNsIEditActionListenerImplementation = {
|
||||
DidCreateNode: function(tag, node, parent, position, result)
|
||||
{
|
||||
//alert('did create node');
|
||||
},
|
||||
|
||||
// TODO: Check if deleted node contains a control, not only if it is one
|
||||
DidDeleteNode: function(child, result)
|
||||
{
|
||||
if(!editor.inResize && !editor.dragState &&
|
||||
!editor.inUpdate && !editor.inCommandExec) {
|
||||
var control = editor.removeLastDeletedControl ();
|
||||
if(control) {
|
||||
var deletionStr = 'deleteControl(s):';
|
||||
deletionStr += ' id=' + control + ',';
|
||||
editor.removeFromControlTable (control);
|
||||
host.removeControl (control);
|
||||
dump (deletionStr +
|
||||
' Message source: DidDeleteNode()');
|
||||
dump ('There is/are '
|
||||
+ editor.controlCount
|
||||
+ ' controls left in the page');
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
// For each element in to-be-deleted array, remove control from the control
|
||||
// table, let the host know we have deleted a control by calling the
|
||||
// respective method, and remove from to-be-deleted array.
|
||||
DidDeleteSelection: function(selection)
|
||||
{
|
||||
if(!editor.inResize && !editor.dragState &&
|
||||
!editor.inUpdate && !editor.inCommandExec) {
|
||||
var control = editor.removeLastDeletedControl ();
|
||||
if(control) {
|
||||
var deletionStr = 'Did delete control(s):';
|
||||
while(control) {
|
||||
deletionStr += ' id=' + control + ',';
|
||||
editor.removeFromControlTable (control);
|
||||
host.removeControl (control);
|
||||
control = editor.removeLastDeletedControl ();
|
||||
}
|
||||
dump (deletionStr +
|
||||
' Message source: DidDeleteSelection()');
|
||||
dump ('There is/are ' +
|
||||
editor.controlCount +
|
||||
' controls left in the page');
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
DidDeleteText: function(textNode, offset, length, result)
|
||||
{
|
||||
|
||||
},
|
||||
|
||||
// Make sure to check node contents for controls too. The node could be
|
||||
// a table (or any other element) with a control inside.
|
||||
DidInsertNode: function(node, parent, position, result)
|
||||
{
|
||||
var dumpStr = 'Did insert node ' + node.nodeName;
|
||||
dumpStr += (node.nodeType == 1) ?
|
||||
', id=' + node.getAttribute(ID) :
|
||||
'';
|
||||
dump (dumpStr);
|
||||
|
||||
// Check to see if we have inserted a new controls. We need to
|
||||
// add'em to the control table. Also update reference to all
|
||||
// existing controls
|
||||
var controls =
|
||||
editor.base.document.getElementsByTagName (CONTROL_TAG_NAME);
|
||||
if(controls.length > 0) {
|
||||
var i = 0;
|
||||
var width, height;
|
||||
while(controls [i]) {
|
||||
if(editor.getControlTable ().getById (controls [i].getAttribute (ID))) {
|
||||
editor.getControlTable ().update (controls [i].getAttribute (ID),
|
||||
controls [i]);
|
||||
dump ('Did update control(id=' +
|
||||
controls [i].getAttribute (ID) +
|
||||
') reference in table');
|
||||
}
|
||||
else {
|
||||
editor.insertInControlTable (controls [i].getAttribute (ID),
|
||||
controls [i]);
|
||||
|
||||
dump ('New control (id=' +
|
||||
controls [i].getAttribute (ID) +
|
||||
') inserted');
|
||||
dump ('There is/are ' +
|
||||
editor.controlCount +
|
||||
' controls in the page');
|
||||
}
|
||||
editor.setSelectNone (controls [i]);
|
||||
width = controls [i].getAttribute(WIDTH);
|
||||
height = controls [i].getAttribute(HEIGHT);
|
||||
controls [i].style.setProperty (MIN_WIDTH,
|
||||
width, '');
|
||||
controls [i].style.setProperty (MIN_HEIGHT,
|
||||
height, '');
|
||||
|
||||
// Create a NodeIterator to find <table>
|
||||
// tags
|
||||
var tables =
|
||||
editor.base.document.createTreeWalker(controls [i],
|
||||
NodeFilter.SHOW_ELEMENT,
|
||||
tableFilter,
|
||||
false);
|
||||
|
||||
// Use the iterator to loop through all
|
||||
// tables
|
||||
editor.cancelTableOverrideStyle (tables);
|
||||
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
if(editor.dragState) {
|
||||
dump ('End drag');
|
||||
}
|
||||
|
||||
if(editor.nodeIsControl (node) &&
|
||||
(node.nodeType == 1 || node.nodeType == 3)) {
|
||||
//editor.selectControl (node.getAttribute (ID));
|
||||
}
|
||||
if(editor.dragState)
|
||||
editor.dragState = false;
|
||||
},
|
||||
|
||||
DidInsertText: function(textNode, offset, string, result)
|
||||
{
|
||||
|
||||
},
|
||||
|
||||
DidJoinNodes: function(leftNode, rightNode, parent, result)
|
||||
{
|
||||
//alert('did join nodes');
|
||||
},
|
||||
|
||||
DidSplitNode: function(existingRightNode, offset, newLeftNode, result)
|
||||
{
|
||||
//alert('did split node');
|
||||
},
|
||||
|
||||
WillCreateNode: function(tag, parent, position)
|
||||
{
|
||||
//alert ('Will create node');
|
||||
},
|
||||
|
||||
WillDeleteNode: function(child)
|
||||
{
|
||||
dump ('will delete node-----------------------');
|
||||
if(!editor.inResize && !editor.dragState &&
|
||||
!editor.inUpdate && !editor.inCommandExec) {
|
||||
var deletionStr = 'Will delete control(s):';
|
||||
var i = 0;
|
||||
|
||||
// is the node itself control?
|
||||
if(editor.nodeIsControl (child)) {
|
||||
deletionStr += ' id=' +
|
||||
child.getAttribute (ID) + ',';
|
||||
editor.addLastDeletedControl (child.getAttribute (ID));
|
||||
}
|
||||
|
||||
// does the node contain any controls?
|
||||
var control = editor.getControlFromTableByIndex (i);
|
||||
while(control) {
|
||||
if(editor.isControlChildOf (child, control)) {
|
||||
deletionStr += ' id=' +
|
||||
control.getAttribute (ID) + ',';
|
||||
editor.addLastDeletedControl (control.getAttribute (ID));
|
||||
}
|
||||
i++;
|
||||
control = editor.getControlFromTableByIndex (i);
|
||||
}
|
||||
if(deletionStr != 'Will delete control(s):')
|
||||
dump (deletionStr +
|
||||
' Message source: WillDeleteNode()');
|
||||
}
|
||||
},
|
||||
|
||||
// Check if the selection to be deleted contains controls and prepare
|
||||
//for deletion. Load all to-be-deleted controls in an array, so we can
|
||||
// access them after actual deletion in order to notify the host.
|
||||
WillDeleteSelection: function(selection)
|
||||
{
|
||||
dump ('will delete selection----------context:' +
|
||||
'inResize=' + editor.inResize + ', ' +
|
||||
'dragState=' + editor.dragState + ', ' +
|
||||
'inUpdate=' + editor.inUpdate + ', ' +
|
||||
'inCommandExec=' + editor.inCommandExec);
|
||||
if(!editor.inResize && !editor.dragState &&
|
||||
!editor.inUpdate && !editor.inCommandExec) {
|
||||
var i = 0;
|
||||
var control = editor.getControlFromTableByIndex (i);
|
||||
var deletionStr = 'Will delete control(s):';
|
||||
if(control) {
|
||||
while(control) {
|
||||
if(selection.containsNode (control, true)) {
|
||||
deletionStr += ' id=' +
|
||||
control.getAttribute (ID) + ',';
|
||||
editor.addLastDeletedControl (control.getAttribute (ID));
|
||||
}
|
||||
i++;
|
||||
control = editor.getControlFromTableByIndex (i);
|
||||
}
|
||||
if(deletionStr != 'Will delete control(s):')
|
||||
dump (deletionStr +
|
||||
' Message source: WillDeleteSelection()');
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
WillDeleteText: function(textNode, offset, length)
|
||||
{
|
||||
|
||||
},
|
||||
|
||||
WillInsertNode: function(node, parent, position)
|
||||
{
|
||||
|
||||
},
|
||||
|
||||
WillInsertText: function(textNode, offset, string)
|
||||
{
|
||||
|
||||
},
|
||||
|
||||
WillJoinNodes: function(leftNode, rightNode, parent)
|
||||
{
|
||||
//alert ('Will join node');
|
||||
},
|
||||
|
||||
WillSplitNode: function(existingRightNode, offset)
|
||||
{
|
||||
//alert ('Will split node');
|
||||
},
|
||||
}
|
||||
|
||||
// nsIHTMLObjectResizeListener implementation
|
||||
var gNsIHTMLObjectResizeListenerImplementation = {
|
||||
onEndResizing: function(element, oldWidth, oldHeight, newWidth, newHeight)
|
||||
{
|
||||
if(editor.nodeIsControl (element)) {
|
||||
var id = element.getAttribute (ID);
|
||||
host.resizeControl (id, newWidth, newHeight);
|
||||
}
|
||||
editor.inResize = false;
|
||||
dump ('End resize.');
|
||||
},
|
||||
|
||||
onStartResizing: function(element)
|
||||
{
|
||||
if(editor.nodeIsControl (element)) {
|
||||
editor.beginBatch ();
|
||||
}
|
||||
editor.inResize = true;
|
||||
dump ('Begin resize.');
|
||||
}
|
||||
}
|
||||
|
||||
// nsIContentFilter implementation
|
||||
// In future we should use this one to manage all insertion coming from
|
||||
// paste, drag&drop, insertHTML(), and page load. Currently not working.
|
||||
// Mozilla throws an INVALID_POINTER exception
|
||||
var gNsIContentFilterImplementation = {
|
||||
notifyOfInsertion: function(mimeType,
|
||||
contentSourceURL,
|
||||
sourceDocument,
|
||||
willDeleteSelection,
|
||||
docFragment,
|
||||
contentStartNode,
|
||||
contentStartOffset,
|
||||
contentEndNode,
|
||||
contentEndOffset,
|
||||
insertionPointNode,
|
||||
insertionPointOffset,
|
||||
continueWithInsertion)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
Загрузка…
Ссылка в новой задаче