blob: aeae0624a4a005b28db0a254351ff8e082c96a33 [file] [log] [blame]
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
// This file comes from the portion of the UX Write editor that
// works on both Apple platforms (that is, it can run on either
// OS X or iOS). It's in the repository for illustrative purposes
// only, to assist with the creation of the framework for the
// Corinthia editor UI. The code does not compile independently in
// its present form.
#import "EDJSInterface.h"
#import "EDScan.h"
#import "EDUtil.h"
#import <FileClient/FCError.h>
#import <FileClient/FCUtil.h>
typedef enum {
AutoCorrect_correctPrecedingWord,
AutoCorrect_getCorrection,
AutoCorrect_getCorrectionCoords,
AutoCorrect_acceptCorrection,
AutoCorrect_replaceCorrection,
ChangeTracking_showChanges,
ChangeTracking_trackChanges,
ChangeTracking_setShowChanges,
ChangeTracking_setTrackChanges,
Clipboard_cut,
Clipboard_copy,
Clipboard_pasteHTML,
Clipboard_pasteText,
Cursor_positionCursor,
Cursor_getCursorPosition,
Cursor_moveLeft,
Cursor_moveRight,
Cursor_moveToStartOfDocument,
Cursor_moveToEndOfDocument,
Cursor_insertReference,
Cursor_insertLink,
Cursor_insertCharacter,
Cursor_deleteCharacter,
Cursor_enterPressed,
Cursor_getPrecedingWord,
Cursor_getLinkProperties,
Cursor_setLinkProperties,
Cursor_setReferenceTarget,
Cursor_insertFootnote,
Cursor_insertEndnote,
Editor_getBackMessages,
Equations_insertEquation,
Figures_insertFigure,
Figures_getSelectedFigureId,
Figures_getProperties,
Figures_setProperties,
Figures_getGeometry,
Formatting_getFormatting,
Formatting_applyFormattingChanges,
Input_removePosition,
Input_textInRange,
Input_replaceRange,
Input_selectedTextRange,
Input_setSelectedTextRange,
Input_markedTextRange,
Input_setMarkedText,
Input_unmarkText,
Input_forwardSelectionAffinity,
Input_setForwardSelectionAffinity,
Input_positionFromPositionOffset,
Input_positionFromPositionInDirectionOffset,
Input_comparePositionToPosition,
Input_offsetFromPositionToPosition,
Input_positionWithinRangeFarthestInDirection,
Input_characterRangeByExtendingPositionInDirection,
Input_firstRectForRange,
Input_caretRectForPosition,
Input_closestPositionToPoint,
Input_closestPositionToPointWithinRange,
Input_characterRangeAtPoint,
Input_positionWithinRangeAtCharacterOffset,
Input_characterOffsetOfPositionWithinRange,
Input_isPositionAtBoundaryGranularityInDirection,
Input_isPositionWithinTextUnitInDirection,
Input_positionFromPositionToBoundaryInDirection,
Input_rangeEnclosingPositionWithGranularityInDirection,
Lists_increaseIndent,
Lists_decreaseIndent,
Lists_clearList,
Lists_setUnorderedList,
Lists_setOrderedList,
Main_getLanguage,
Main_setLanguage,
Main_setGenerator,
Main_init,
Main_getErrorReportingInfo,
Main_execute,
Main_prepareForSave,
Main_getHTML,
Main_isEmptyDocument,
Metadata_getMetadata,
Metadata_setMetadata,
Outline_moveSection,
Outline_deleteItem,
Outline_goToItem,
Outline_scheduleUpdateStructure,
Outline_setNumbered,
Outline_setTitle,
Outline_getOutline,
Outline_insertTableOfContents,
Outline_insertListOfFigures,
Outline_insertListOfTables,
Outline_setPrintMode,
Outline_examinePrintLayout,
Outline_detectSectionNumbering,
Outline_findUsedStyles,
Preview_showForStyle,
Scan_reset,
Scan_next,
Scan_addMatch,
Scan_showMatch,
Scan_replaceMatch,
Scan_removeMatch,
Scan_goToMatch,
Selection_update,
Selection_selectAll,
Selection_selectParagraph,
Selection_selectWordAtCursor,
Selection_dragSelectionBegin,
Selection_dragSelectionUpdate,
Selection_moveStartLeft,
Selection_moveStartRight,
Selection_moveEndLeft,
Selection_moveEndRight,
Selection_setSelectionStartAtCoords,
Selection_setSelectionEndAtCoords,
Selection_setTableSelectionEdgeAtCoords,
Selection_print,
Styles_getCSSText,
Styles_setCSSText,
Styles_getParagraphClass,
Styles_setParagraphClass,
Tables_insertTable,
Tables_addAdjacentRow,
Tables_addAdjacentColumn,
Tables_removeAdjacentRow,
Tables_removeAdjacentColumn,
Tables_clearCells,
Tables_mergeCells,
Tables_splitSelection,
Tables_getSelectedTableId,
Tables_getProperties,
Tables_setProperties,
Tables_setColWidths,
Tables_getGeometry,
UndoManager_getLength,
UndoManager_getIndex,
UndoManager_setIndex,
UndoManager_undo,
UndoManager_redo,
UndoManager_newGroup,
UndoManager_groupType,
Viewport_setViewportWidth,
Viewport_setTextScale,
JSInterfaceFunctionCount,
} JSInterfaceFunction;
static BOOL functionModifiesDocument(JSInterfaceFunction fun)
{
switch (fun)
{
case AutoCorrect_correctPrecedingWord:
case AutoCorrect_acceptCorrection:
case AutoCorrect_replaceCorrection:
case ChangeTracking_setShowChanges:
case ChangeTracking_setTrackChanges:
case Clipboard_cut:
case Clipboard_pasteHTML:
case Clipboard_pasteText:
case Cursor_insertReference:
case Cursor_insertLink:
case Cursor_insertCharacter:
case Cursor_deleteCharacter:
case Cursor_enterPressed:
case Cursor_setLinkProperties:
case Cursor_setReferenceTarget:
case Cursor_insertFootnote:
case Cursor_insertEndnote:
case Equations_insertEquation:
case Figures_insertFigure:
case Figures_setProperties:
case Formatting_applyFormattingChanges:
case Lists_increaseIndent:
case Lists_decreaseIndent:
case Lists_clearList:
case Lists_setUnorderedList:
case Lists_setOrderedList:
case Main_setLanguage:
case Main_prepareForSave:
case Metadata_setMetadata:
case Outline_moveSection:
case Outline_deleteItem:
case Outline_scheduleUpdateStructure:
case Outline_setNumbered:
case Outline_setTitle:
case Outline_insertTableOfContents:
case Outline_insertListOfFigures:
case Outline_insertListOfTables:
case Outline_setPrintMode:
case Outline_examinePrintLayout:
case Scan_replaceMatch:
case Styles_setCSSText:
case Tables_insertTable:
case Tables_addAdjacentRow:
case Tables_addAdjacentColumn:
case Tables_removeAdjacentRow:
case Tables_removeAdjacentColumn:
case Tables_clearCells:
case Tables_mergeCells:
case Tables_splitSelection:
case Tables_setProperties:
case Tables_setColWidths:
case UndoManager_undo:
case UndoManager_redo:
return true;
case AutoCorrect_getCorrection:
case AutoCorrect_getCorrectionCoords:
case ChangeTracking_showChanges:
case ChangeTracking_trackChanges:
case Clipboard_copy:
case Cursor_positionCursor:
case Cursor_getCursorPosition:
case Cursor_moveLeft:
case Cursor_moveRight:
case Cursor_moveToStartOfDocument:
case Cursor_moveToEndOfDocument:
case Cursor_getPrecedingWord:
case Cursor_getLinkProperties:
case Editor_getBackMessages:
case Figures_getSelectedFigureId:
case Figures_getProperties:
case Figures_getGeometry:
case Formatting_getFormatting:
case Input_removePosition:
case Input_textInRange:
case Input_replaceRange:
case Input_selectedTextRange:
case Input_setSelectedTextRange:
case Input_markedTextRange:
case Input_setMarkedText:
case Input_unmarkText:
case Input_forwardSelectionAffinity:
case Input_setForwardSelectionAffinity:
case Input_positionFromPositionOffset:
case Input_positionFromPositionInDirectionOffset:
case Input_comparePositionToPosition:
case Input_offsetFromPositionToPosition:
case Input_positionWithinRangeFarthestInDirection:
case Input_characterRangeByExtendingPositionInDirection:
case Input_firstRectForRange:
case Input_caretRectForPosition:
case Input_closestPositionToPoint:
case Input_closestPositionToPointWithinRange:
case Input_characterRangeAtPoint:
case Input_positionWithinRangeAtCharacterOffset:
case Input_characterOffsetOfPositionWithinRange:
case Input_isPositionAtBoundaryGranularityInDirection:
case Input_isPositionWithinTextUnitInDirection:
case Input_positionFromPositionToBoundaryInDirection:
case Input_rangeEnclosingPositionWithGranularityInDirection:
case Main_getLanguage:
case Main_setGenerator:
case Main_init:
case Main_getErrorReportingInfo:
case Main_execute:
case Main_getHTML:
case Main_isEmptyDocument:
case Metadata_getMetadata:
case Outline_getOutline:
case Outline_goToItem:
case Outline_detectSectionNumbering:
case Outline_findUsedStyles:
case Preview_showForStyle:
case Scan_reset:
case Scan_next:
case Scan_addMatch:
case Scan_showMatch:
case Scan_removeMatch:
case Scan_goToMatch:
case Selection_update:
case Selection_selectAll:
case Selection_selectParagraph:
case Selection_selectWordAtCursor:
case Selection_dragSelectionBegin:
case Selection_dragSelectionUpdate:
case Selection_moveStartLeft:
case Selection_moveStartRight:
case Selection_moveEndLeft:
case Selection_moveEndRight:
case Selection_setSelectionStartAtCoords:
case Selection_setSelectionEndAtCoords:
case Selection_setTableSelectionEdgeAtCoords:
case Selection_print:
case Styles_getCSSText:
case Styles_getParagraphClass:
case Styles_setParagraphClass:
case Tables_getSelectedTableId:
case Tables_getProperties:
case Tables_getGeometry:
case UndoManager_getLength:
case UndoManager_getIndex:
case UndoManager_setIndex:
case UndoManager_newGroup:
case UndoManager_groupType:
case Viewport_setViewportWidth:
case Viewport_setTextScale:
case JSInterfaceFunctionCount:
return false;
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// JSError //
// //
////////////////////////////////////////////////////////////////////////////////////////////////////
@implementation JSError
- (JSError *)initWithType:(NSString *)type
message:(NSString *)message
operation:(NSString *)operation
html:(NSString *)html
{
if (!(self = [super init]))
return nil;
_type = [type copy];
_message = [message copy];
_operation = [operation copy];
_html = [html copy];
return self;
}
- (NSString *)description
{
NSMutableString *errorInfo = [NSMutableString stringWithCapacity: 0];
[errorInfo appendFormat: @"%@\n", _message];
[errorInfo appendFormat: @"Operation: %@\n", _operation];
[errorInfo appendFormat: @"\n"];
[errorInfo appendFormat: @"HTML:\n%@\n", _html];
return errorInfo;
}
- (NSString *)localizedDescription
{
return [self description];
}
@end
////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// JSInterface //
// //
////////////////////////////////////////////////////////////////////////////////////////////////////
@implementation JSInterface
{
NSUInteger _numCalls[JSInterfaceFunctionCount];
NSTimeInterval _timeUsed[JSInterfaceFunctionCount];
NSTimeInterval _totalTimeUsed;
}
- (JSInterface *)initWithEvaluator:(NSObject<JSEvaluator> *)evaluator
{
if (!(self = [super init]))
return nil;
_evaluator = evaluator;
_autoCorrect = [[JSAutoCorrect alloc] initWithJS: self];
_changeTracking = [[JSChangeTracking alloc] initWithJS: self];
_clipboard = [[JSClipboard alloc] initWithJS: self];
_cursor = [[JSCursor alloc] initWithJS: self];
_equations = [[JSEquations alloc] initWithJS: self];
_figures = [[JSFigures alloc] initWithJS: self];
_formatting = [[JSFormatting alloc] initWithJS: self];
_input = [[JSInput alloc] initWithJS: self];
_lists = [[JSLists alloc] initWithJS: self];
_main = [[JSMain alloc] initWithJS: self];
_metadata = [[JSMetadata alloc] initWithJS: self];
_outline = [[JSOutline alloc] initWithJS: self];
_preview = [[JSPreview alloc] initWithJS: self];
_scan = [[JSScan alloc] initWithJS: self];
_selection = [[JSSelection alloc] initWithJS: self];
_styles = [[JSStyles alloc] initWithJS: self];
_tables = [[JSTables alloc] initWithJS: self];
_undoManager = [[JSUndoManager alloc] initWithJS: self];
_viewport = [[JSViewport alloc] initWithJS: self];
return self;
}
- (void)dealloc
{
_autoCorrect.js = nil;
_changeTracking.js = nil;
_clipboard.js = nil;
_cursor.js = nil;
_equations.js = nil;
_figures.js = nil;
_formatting.js = nil;
_input.js = nil;
_lists.js = nil;
_main.js = nil;
_metadata.js = nil;
_outline.js = nil;
_preview.js = nil;
_scan.js = nil;
_selection.js = nil;
_styles.js = nil;
_tables.js = nil;
_undoManager.js = nil;
_viewport.js = nil;
}
- (BOOL)initJavaScriptWidth:(int)width textScale:(int)textScale cssURL:(NSString *)cssURL
clientRectsBug:(BOOL)clientRectsBug
{
// Special case javascript call to Main_init(). We don't use the normal mechanism here because
// at this point the JS interface has not been initialised, and the check for this in
// executeJavaScriptWithJSONResult would cause it to fail.
NSString *code = [NSString stringWithFormat: @"interface_functions[%d](%d,%d,\"%@\",%@)",
Main_init, width, textScale, cssURL, clientRectsBug ? @"true" : @"false"];
NSString *result = [_evaluator stringByEvaluatingJavaScriptFromString: code];
[self jsCallCompleted];
if ([@"true" isEqualToString: result]) {
return YES;
}
else {
self.currentOperation = @"JavaScript initialisation";
[self reportErrorWithType: nil format: @"%@", result];
self.currentOperation = nil;
return NO;
}
}
- (void)jsCallCompleted
{
// Process pending callbacks
NSString *getBackMessages = [NSString stringWithFormat: @"interface_functions[%d]()",
Editor_getBackMessages];
NSString *str = [_evaluator stringByEvaluatingJavaScriptFromString: getBackMessages];
NSData *data = [str dataUsingEncoding: NSUTF8StringEncoding];
NSArray *array = [NSJSONSerialization JSONObjectWithData: data options: 0 error: nil];
for (NSArray *message in array)
[self dispatchCallbackMessage: message];
}
- (NSString *)operationStringWithFunction:(JSInterfaceFunction)function nargs:(int)nargs arguments:(va_list)ap
{
NSMutableString *operation = [NSMutableString stringWithCapacity: 0];
[operation appendFormat: @"interface_functions[%d](", function];
NSObject *arg;
for (int argno = 0; argno < nargs; argno++) {
arg = va_arg(ap,NSObject*);
if (argno > 0)
[operation appendString: @","];
if (arg == nil) {
[operation appendString: @"null"];
}
else if ([arg isKindOfClass: [NSNumber class]]) {
[operation appendString: [arg description]];
}
else if ([arg isKindOfClass: [NSNull class]]) {
[operation appendString: @"null"];
}
else if ([arg isKindOfClass: [NSArray class]] || [arg isKindOfClass: [NSDictionary class]]) {
NSError *err = nil;
NSData *data = [NSJSONSerialization dataWithJSONObject: arg options: 0 error: &err];
if (data == nil) {
[NSException raise: @"NSJSONSerialization"
format: @"executeJavaScript %d: cannot serialise argument %d to JSON: %@",
function, argno, FCErrorDescription(err)];
}
else {
NSString *str = [[NSString alloc] initWithBytes: data.bytes length: data.length
encoding: NSUTF8StringEncoding];
[operation appendString: str];
}
}
else {
char *quoted = DFQuote(arg.description.UTF8String);
NSString *nsQuoted = [NSString stringWithUTF8String: quoted];
[operation appendString: nsQuoted];
free(quoted);
}
}
[operation appendString: @")"];
return operation;
}
- (id)executeJavaScriptWithJSONResult:(BOOL)jsonResult function:(JSInterfaceFunction)function nargs:(int)nargs arguments:(va_list)ap
{
NSDate *start = [NSDate date];
if (!_jsInitialised) {
[NSException raise: @"JavaScriptNotInitialised"
format: @"Yet to receive a jsInterfaceInitFinished from JavaScript code"];
}
self.currentOperation = [self operationStringWithFunction: function nargs: nargs arguments: ap];
id result;
if (!jsonResult) {
NSString *code = [NSString stringWithFormat: @"interface_functions[%d](function() { return %@; });",
Main_execute, self.currentOperation];
result = [_evaluator stringByEvaluatingJavaScriptFromString: code];
[self jsCallCompleted];
}
else {
NSString *code = [NSString stringWithFormat: @"interface_functions[%d](function() { return JSON.stringify(%@); });",
Main_execute, self.currentOperation];
NSString *str = [_evaluator stringByEvaluatingJavaScriptFromString: code];
[self jsCallCompleted];
if ([str isEqualToString: @"null"]) {
result = nil;
}
else {
NSData *data = [str dataUsingEncoding: NSUTF8StringEncoding];
NSError *err = nil;
result = [NSJSONSerialization JSONObjectWithData: data options: 0 error: &err];
if (result == nil) {
[self reportErrorWithType: nil format: @"Cannot deserialise JSON result \"%@\": %@",
str, FCErrorDescription(err)];
}
}
}
NSDate *end = [NSDate date];
NSTimeInterval interval = [end timeIntervalSinceDate: start];
_numCalls[function]++;
_timeUsed[function] += interval;
_totalTimeUsed += interval;
self.currentOperation = nil;
if (functionModifiesDocument(function))
self.documentModified = YES;
return result;
}
- (void)printStatistics
{
if (_totalTimeUsed == 0.0)
return;
printf("\n");
printf("%-10s %-10s %-10s %-10s\n","Function","Calls","Time","Time pct");
NSMutableArray *order = [NSMutableArray arrayWithCapacity: 0];
for (NSUInteger i = 0; i < JSInterfaceFunctionCount; i++)
[order addObject: [NSNumber numberWithUnsignedInteger: i]];
[order sortUsingComparator:^NSComparisonResult(NSNumber *n1, NSNumber *n2) {
NSUInteger i1 = n1.unsignedIntValue;
NSUInteger i2 = n2.unsignedIntValue;
if (_timeUsed[i1] < _timeUsed[i2])
return NSOrderedAscending;
else if (_timeUsed[i1] > _timeUsed[i2])
return NSOrderedDescending;
else
return NSOrderedSame;
}];
for (NSNumber *n in order) {
NSUInteger i = n.unsignedIntValue;
double pct = 100*(_timeUsed[i]/_totalTimeUsed);
if (pct >= 0.01) {
printf("%-10d %-10d %-10d %.2f%%\n",(int)i,(int)_numCalls[i],(int)(_timeUsed[i]*1000),pct);
}
}
printf("totalTimeUsed = %.2fms\n",1000*_totalTimeUsed);
}
- (id)executeJavaScriptJSON:(JSInterfaceFunction)function nargs:(int)nargs, ...
{
va_list ap;
va_start(ap,nargs);
NSString *result = (NSString *)[self executeJavaScriptWithJSONResult: YES
function: function
nargs: nargs
arguments: ap];
va_end(ap);
return result;
}
- (NSString *)executeJavaScript:(JSInterfaceFunction)function nargs:(int)nargs, ...
{
va_list ap;
va_start(ap,nargs);
NSString *result = (NSString *)[self executeJavaScriptWithJSONResult: NO
function: function
nargs: nargs
arguments: ap];
va_end(ap);
return result;
}
- (void)dispatchCallbackMessage:(NSArray*)array
{
if (array.count == 0)
return;
if (![[array objectAtIndex: 0] isKindOfClass: [NSString class]])
return;
NSString *functionName = [array objectAtIndex: 0];
if ([functionName isEqualToString: @"debug"] &&
([array count] == 2) &&
[[array objectAtIndex: 1] isKindOfClass: [NSString class]]) {
NSString *message = [array objectAtIndex: 1];
debug(@"%@\n",message);
}
else if ([functionName isEqualToString: @"addOutlineItem"] &&
[_delegate respondsToSelector: @selector(jsAddOutlineItem:type:title:)] &&
([array count] == 4) &&
[[array objectAtIndex: 1] isKindOfClass: [NSString class]] &&
[[array objectAtIndex: 2] isKindOfClass: [NSString class]]) {
// 3 could be a a string or null
NSString *title = [array objectAtIndex: 3];
if ([title isKindOfClass: [NSNull class]])
title = nil;
[_delegate jsAddOutlineItem: [array objectAtIndex: 1]
type: [array objectAtIndex: 2]
title: title];
}
else if ([functionName isEqualToString: @"updateOutlineItem"] &&
[_delegate respondsToSelector: @selector(jsUpdateOutlineItem:title:)] &&
([array count] == 3) &&
[[array objectAtIndex: 1] isKindOfClass: [NSString class]] &&
[[array objectAtIndex: 2] isKindOfClass: [NSString class]]) {
[_delegate jsUpdateOutlineItem: [array objectAtIndex: 1] title: [array objectAtIndex: 2]];
}
else if ([functionName isEqualToString: @"removeOutlineItem"] &&
[_delegate respondsToSelector: @selector(jsRemoveOutlineItem:)] &&
([array count] == 2) &&
[[array objectAtIndex: 1] isKindOfClass: [NSString class]]) {
[_delegate jsRemoveOutlineItem: [array objectAtIndex: 1]];
}
else if ([functionName isEqualToString: @"outlineUpdated"] &&
[_delegate respondsToSelector: @selector(jsOutlineUpdated)] &&
[array count] == 1) {
[_delegate jsOutlineUpdated];
}
else if ([functionName isEqualToString: @"setSelectionHandles"] &&
[_delegate respondsToSelector: @selector(jsSetSelectionHandlesX1:y1:height1:x2:y2:height2:)] &&
([array count] == 7) &&
([[array objectAtIndex: 1] isKindOfClass: [NSNumber class]]) &&
([[array objectAtIndex: 2] isKindOfClass: [NSNumber class]]) &&
([[array objectAtIndex: 3] isKindOfClass: [NSNumber class]]) &&
([[array objectAtIndex: 4] isKindOfClass: [NSNumber class]]) &&
([[array objectAtIndex: 5] isKindOfClass: [NSNumber class]]) &&
([[array objectAtIndex: 6] isKindOfClass: [NSNumber class]])) {
[_delegate jsSetSelectionHandlesX1: ((NSNumber *)[array objectAtIndex: 1]).intValue
y1: ((NSNumber *)[array objectAtIndex: 2]).intValue
height1: ((NSNumber *)[array objectAtIndex: 3]).intValue
x2: ((NSNumber *)[array objectAtIndex: 4]).intValue
y2: ((NSNumber *)[array objectAtIndex: 5]).intValue
height2: ((NSNumber *)[array objectAtIndex: 6]).intValue];
}
else if ([functionName isEqualToString: @"setTableSelection"] &&
[_delegate respondsToSelector: @selector(jsSetTableSelectionX:y:width:height:)] &&
([array count] == 5) &&
([[array objectAtIndex: 1] isKindOfClass: [NSNumber class]]) &&
([[array objectAtIndex: 2] isKindOfClass: [NSNumber class]]) &&
([[array objectAtIndex: 3] isKindOfClass: [NSNumber class]]) &&
([[array objectAtIndex: 4] isKindOfClass: [NSNumber class]])) {
[_delegate jsSetTableSelectionX: ((NSNumber *)[array objectAtIndex: 1]).intValue
y: ((NSNumber *)[array objectAtIndex: 2]).intValue
width: ((NSNumber *)[array objectAtIndex: 3]).intValue
height: ((NSNumber *)[array objectAtIndex: 4]).intValue];
}
else if ([functionName isEqualToString: @"setCursor"] &&
[_delegate respondsToSelector: @selector(jsSetCursorX:y:width:height:)] &&
([array count] == 5) &&
([[array objectAtIndex: 1] isKindOfClass: [NSNumber class]]) &&
([[array objectAtIndex: 2] isKindOfClass: [NSNumber class]]) &&
([[array objectAtIndex: 3] isKindOfClass: [NSNumber class]]) &&
([[array objectAtIndex: 4] isKindOfClass: [NSNumber class]])) {
[_delegate jsSetCursorX: ((NSNumber *)[array objectAtIndex: 1]).intValue
y: ((NSNumber *)[array objectAtIndex: 2]).intValue
width: ((NSNumber *)[array objectAtIndex: 3]).intValue
height: ((NSNumber *)[array objectAtIndex: 4]).intValue];
}
else if ([functionName isEqualToString: @"clearSelectionHandlesAndCursor"] &&
[_delegate respondsToSelector: @selector(jsClearSelectionHandlesAndCursor)] &&
([array count] == 1)) {
[_delegate jsClearSelectionHandlesAndCursor];
}
else if ([functionName isEqualToString: @"setSelectionBounds"] &&
[_delegate respondsToSelector: @selector(jsSetSelectionBoundsLeft:top:right:bottom:)] &&
([array count] == 5) &&
([[array objectAtIndex: 1] isKindOfClass: [NSNumber class]]) &&
([[array objectAtIndex: 2] isKindOfClass: [NSNumber class]]) &&
([[array objectAtIndex: 3] isKindOfClass: [NSNumber class]]) &&
([[array objectAtIndex: 4] isKindOfClass: [NSNumber class]])) {
[_delegate jsSetSelectionBoundsLeft: ((NSNumber *)[array objectAtIndex: 1]).intValue
top: ((NSNumber *)[array objectAtIndex: 2]).intValue
right: ((NSNumber *)[array objectAtIndex: 3]).intValue
bottom: ((NSNumber *)[array objectAtIndex: 4]).intValue];
}
else if ([functionName isEqualToString: @"updateAutoCorrect"] &&
[_delegate respondsToSelector: @selector(jsUpdateAutoCorrect)]) {
[_delegate jsUpdateAutoCorrect];
}
else if ([functionName isEqualToString: @"error"] &&
(array.count == 3) &&
[[array objectAtIndex: 1] isKindOfClass: [NSString class]] &&
[[array objectAtIndex: 2] isKindOfClass: [NSString class]]) {
NSString *message = [array objectAtIndex: 1];
NSString *type = [array objectAtIndex: 2];
if (type.length == 0)
type = nil;
[self reportErrorWithType: type format: @"%@", message];
}
}
- (void)reportErrorWithType:(NSString *)type format:(NSString *)format, ...
{
if (self.error != nil)
return;
va_list ap;
va_start(ap,format);
NSString *basicError = [[NSString alloc] initWithFormat: format arguments: ap];
va_end(ap);
NSString *getErrorReportingInfo = [NSString stringWithFormat: @"interface_functions[%d]()",
Main_getErrorReportingInfo];
NSString *html = [_evaluator stringByEvaluatingJavaScriptFromString: getErrorReportingInfo];
self.error = [[JSError alloc] initWithType: type
message: basicError
operation: self.currentOperation
html: html];
}
@end
////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// JSModule //
// //
////////////////////////////////////////////////////////////////////////////////////////////////////
@implementation JSModule
- (JSModule *)initWithJS:(JSInterface *)js
{
if (!(self = [super init]))
return nil;
_js = js;
return self;
}
@end
////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// JSAutoCorrect //
// //
////////////////////////////////////////////////////////////////////////////////////////////////////
@implementation JSAutoCorrect
- (void)correctPreceding:(int)numChars word:(NSString *)replacement confirmed:(BOOL)confirmed;
{
[self.js executeJavaScript: AutoCorrect_correctPrecedingWord nargs: 3,
[NSNumber numberWithInt: numChars], replacement, [NSNumber numberWithBool: confirmed]];
}
- (NSDictionary *)getCorrection
{
return [self.js executeJavaScriptJSON: AutoCorrect_getCorrection nargs: 0];
}
- (NSDictionary *)getCorrectionCoords
{
return [self.js executeJavaScriptJSON: AutoCorrect_getCorrectionCoords nargs: 0];
}
- (void)acceptCorrection
{
[self.js executeJavaScript: AutoCorrect_acceptCorrection nargs: 0];
}
- (void)replaceCorrection:(NSString *)replacement
{
[self.js executeJavaScript: AutoCorrect_replaceCorrection nargs: 1, replacement];
}
@end
////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// JSChangeTracking //
// //
////////////////////////////////////////////////////////////////////////////////////////////////////
@implementation JSChangeTracking
- (BOOL)showChanges
{
NSString *result = [self.js executeJavaScript: ChangeTracking_showChanges nargs: 0];
return [result isEqualToString: @"true"];
}
- (BOOL)trackChanges
{
NSString *result = [self.js executeJavaScript: ChangeTracking_trackChanges nargs: 0];
return [result isEqualToString: @"true"];
}
- (void)setShowChanges:(BOOL)showChanges
{
[self.js executeJavaScript: ChangeTracking_setShowChanges
nargs: 1, [NSNumber numberWithBool: showChanges]];
}
- (void)setTrackChanges:(BOOL)trackChanges
{
[self.js executeJavaScript: ChangeTracking_setTrackChanges
nargs: 1, [NSNumber numberWithBool: trackChanges]];
}
@end
////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// JSClipboard //
// //
////////////////////////////////////////////////////////////////////////////////////////////////////
@implementation JSClipboard
// The copy operation is called clipboardCopy to keep the static analyzer happy, because it thinks
// that it relates to making a copy of the object and reports a memory leak. The cut operation
// is named similarly just for consistency.
- (NSDictionary *)clipboardCut
{
return [self.js executeJavaScriptJSON: Clipboard_cut nargs: 0];
}
- (NSDictionary *)clipboardCopy
{
return [self.js executeJavaScriptJSON: Clipboard_copy nargs: 0];
}
- (void)pasteHTML:(NSString *)html
{
[self.js executeJavaScript: Clipboard_pasteHTML nargs: 1, html];
}
- (void)pasteText:(NSString *)text
{
[self.js executeJavaScript: Clipboard_pasteText nargs: 1, text];
}
@end
////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// JSCursor //
// //
////////////////////////////////////////////////////////////////////////////////////////////////////
// Functions implemented in Cursor.js
@implementation JSCursor
- (NSString *)positionCursorX:(int)x y:(int)y wordBoundary:(BOOL)wordBoundary
{
return [self.js executeJavaScript: Cursor_positionCursor nargs: 3,
[NSNumber numberWithInt: x], [NSNumber numberWithInt: y],
[NSNumber numberWithBool: wordBoundary]];
}
- (CGRect)getCursorPosition
{
NSDictionary *result = [self.js executeJavaScriptJSON: Cursor_getCursorPosition nargs: 0];
return CGRectMake(NSDictionaryGetInt(result,@"x"),
NSDictionaryGetInt(result,@"y"),
NSDictionaryGetInt(result,@"width"),
NSDictionaryGetInt(result,@"height"));
}
- (void)moveLeft
{
[self.js executeJavaScript: Cursor_moveLeft nargs: 0];
}
- (void)moveRight
{
[self.js executeJavaScript: Cursor_moveRight nargs: 0];
}
- (void)moveToStartOfDocument
{
[self.js executeJavaScript: Cursor_moveToStartOfDocument nargs: 0];
}
- (void)moveToEndOfDocument
{
[self.js executeJavaScript: Cursor_moveToEndOfDocument nargs: 0];
}
- (void)insertReference:(NSString *)itemId
{
[self.js executeJavaScript: Cursor_insertReference nargs: 1, itemId];
}
- (void)insertLinkWithText:(NSString *)text URL:(NSString *)URL
{
[self.js executeJavaScript: Cursor_insertLink nargs: 2, text, URL];
}
- (void)insertCharacter:(unichar)character allowInvalidPos:(BOOL)allowInvalidPos
{
NSString *str = [NSString stringWithFormat: @"%C", character];
[self.js executeJavaScript: Cursor_insertCharacter nargs: 2, str,
[NSNumber numberWithBool: allowInvalidPos]];
}
- (void)deleteCharacter
{
[self.js executeJavaScript: Cursor_deleteCharacter nargs: 0];
}
- (void)enterPressed
{
[self.js executeJavaScript: Cursor_enterPressed nargs: 0];
}
- (NSString *)getPrecedingWord
{
return [self.js executeJavaScript: Cursor_getPrecedingWord nargs: 0];
}
- (NSDictionary *)getLinkProperties
{
return [self.js executeJavaScriptJSON: Cursor_getLinkProperties nargs: 0];
}
- (void)setLinkProperties:(NSDictionary *)properties
{
[self.js executeJavaScript: Cursor_setLinkProperties nargs: 1, properties];
}
- (void)setReferenceTarget:(NSString *)itemId
{
[self.js executeJavaScript: Cursor_setReferenceTarget nargs: 1, itemId];
}
- (void)insertFootnote:(NSString *)content
{
[self.js executeJavaScript: Cursor_insertFootnote nargs: 1, content];
}
- (void)insertEndnote:(NSString *)content
{
[self.js executeJavaScript: Cursor_insertEndnote nargs: 1, content];
}
@end
////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// Equations //
// //
////////////////////////////////////////////////////////////////////////////////////////////////////
@implementation JSEquations
- (void)insertEquation
{
[self.js executeJavaScript: Equations_insertEquation nargs: 0];
}
@end
////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// JSFigures //
// //
////////////////////////////////////////////////////////////////////////////////////////////////////
@implementation JSFigures
- (void)insertFigure:(NSString *)filename width:(NSString *)width
numbered:(BOOL)numbered caption:(NSString *)caption
{
[self.js executeJavaScript: Figures_insertFigure nargs: 4,
filename, width, [NSNumber numberWithBool: numbered], caption];
}
- (NSString *)getSelectedFigureId
{
return [self.js executeJavaScript: Figures_getSelectedFigureId nargs: 0];
}
- (NSDictionary *)getProperties:(NSString *)itemId
{
return [self.js executeJavaScriptJSON: Figures_getProperties nargs: 1, itemId];
}
- (void)setProperties:(NSString *)itemId width:(NSString *)width src:(NSString *)src
{
[self.js executeJavaScript: Figures_setProperties nargs: 3, itemId, width, src];
}
- (NSDictionary *)getGeometry:(NSString *)itemId
{
return [self.js executeJavaScriptJSON: Figures_getGeometry nargs: 1, itemId];
}
@end
////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// JSFormatting //
// //
////////////////////////////////////////////////////////////////////////////////////////////////////
// Functions implemented in Formatting.js
@implementation JSFormatting
- (NSDictionary *)getFormatting
{
return [self.js executeJavaScriptJSON: Formatting_getFormatting nargs: 0];
}
- (void)applyFormattingChangesStyle:(NSString *)style properties:(NSDictionary *)properties
{
[self.js executeJavaScript: Formatting_applyFormattingChanges nargs: 2, style, properties];
}
@end
////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// JSInput //
// //
////////////////////////////////////////////////////////////////////////////////////////////////////
@implementation JSInput
- (void)removePosition:(int)posId
{
[self.js executeJavaScript: Input_removePosition nargs: 1, [NSNumber numberWithInt: posId]];
}
- (NSString *)textInRangeStartId:(int)startId startAdjust:(int)startAdjust
endId:(int)endId endAdjust:(int)endAdjust
{
return [self.js executeJavaScript: Input_textInRange nargs: 4,
[NSNumber numberWithInt: startId],
[NSNumber numberWithInt: startAdjust],
[NSNumber numberWithInt: endId],
[NSNumber numberWithInt: endAdjust]];
}
- (void)replaceRangeStart:(int)startId end:(int)endId withText:(NSString *)text
{
[self.js executeJavaScript: Input_replaceRange nargs: 3,
[NSNumber numberWithInt: startId], [NSNumber numberWithInt: endId], text];
}
- (NSDictionary *)selectedTextRange
{
return [self.js executeJavaScriptJSON: Input_selectedTextRange nargs: 0];
}
- (void)setSelectedTextRangeStart:(int)startId end:(int)endId
{
[self.js executeJavaScript: Input_setSelectedTextRange nargs: 2,
[NSNumber numberWithInt: startId], [NSNumber numberWithInt: endId]];
}
- (NSDictionary *)markedTextRange
{
return [self.js executeJavaScriptJSON: Input_markedTextRange nargs: 0];
}
- (void)setMarkedText:(NSString *)text startOffset:(int)startOffset endOffset:(int)endOffset
{
[self.js executeJavaScript: Input_setMarkedText nargs: 3,
text, [NSNumber numberWithInt: startOffset], [NSNumber numberWithInt: endOffset]];
}
- (void)unmarkText
{
[self.js executeJavaScript: Input_unmarkText nargs: 0];
}
- (BOOL)forwardSelectionAffinity
{
NSString *result = [self.js executeJavaScript: Input_forwardSelectionAffinity nargs: 0];
return [result isEqualToString: @"true"];
}
- (void)setForwardSelectionAffinity:(BOOL)forwardSelectionAffinity
{
[self.js executeJavaScript: Input_setForwardSelectionAffinity nargs: 1,
[NSNumber numberWithBool: forwardSelectionAffinity]];
}
- (int)positionFromPosition:(int)posId offset:(int)offset
{
NSString *result = [self.js executeJavaScript: Input_positionFromPositionOffset nargs: 2,
[NSNumber numberWithInt: posId], [NSNumber numberWithInt: offset]];
return result.intValue;
}
- (int)positionFromPosition:(int)posId inDirection:(NSString *)direction offset:(int)offset
{
NSString *result = [self.js executeJavaScript: Input_positionFromPositionInDirectionOffset nargs: 3,
[NSNumber numberWithInt: posId], direction, [NSNumber numberWithInt: offset]];
return result.intValue;
}
- (int)comparePosition:(int)positionId toPosition:(int)otherId
{
NSString *result = [self.js executeJavaScript: Input_comparePositionToPosition nargs: 2,
[NSNumber numberWithInt: positionId], [NSNumber numberWithInt: otherId]];
return result.intValue;
}
- (int)offsetFromPosition:(int)fromPosition toPosition:(int)toPosition
{
NSString *result = [self.js executeJavaScript: Input_offsetFromPositionToPosition nargs: 2,
[NSNumber numberWithInt: fromPosition], [NSNumber numberWithInt: toPosition]];
return result.intValue;
}
- (int)positionWithinRangeStart:(int)startId end:(int)endId farthestInDirection:(NSString *)direction
{
NSString *result = [self.js executeJavaScript: Input_positionWithinRangeFarthestInDirection nargs: 3,
[NSNumber numberWithInt: startId], [NSNumber numberWithInt: endId], direction];
return result.intValue;
}
- (NSDictionary *)characterRangeByExtendingPosition:(int)positionId inDirection:(NSString *)direction
{
return [self.js executeJavaScriptJSON: Input_characterRangeByExtendingPositionInDirection nargs: 2,
[NSNumber numberWithInt: positionId], direction];
}
- (NSDictionary *)firstRectForRangeStart:(int)startId end:(int)endId
{
return [self.js executeJavaScriptJSON: Input_firstRectForRange nargs: 2,
[NSNumber numberWithInt: startId], [NSNumber numberWithInt: endId]];
}
- (NSDictionary *)caretRectForPosition:(int)posId
{
return [self.js executeJavaScriptJSON: Input_caretRectForPosition nargs: 1,
[NSNumber numberWithInt: posId]];
}
- (int)closestPositionToPointX:(int)x y:(int)y
{
NSString *result = [self.js executeJavaScript: Input_closestPositionToPoint nargs: 2,
[NSNumber numberWithInt: x], [NSNumber numberWithInt: y]];
return result.intValue;
}
- (int)closestPositionToPointX:(int)x y:(int)y withinRangeStart:(int)startId end:(int)endId
{
NSString *result = [self.js executeJavaScript: Input_closestPositionToPointWithinRange nargs: 4,
[NSNumber numberWithInt: x], [NSNumber numberWithInt: y],
[NSNumber numberWithInt: startId], [NSNumber numberWithInt: endId]];
return result.intValue;
}
- (NSDictionary *)characterRangeAtPointX:(int)x y:(int)y
{
return [self.js executeJavaScriptJSON: Input_characterRangeAtPoint nargs: 2,
[NSNumber numberWithInt: x], [NSNumber numberWithInt: y]];
}
- (int)positionWithinRangeStart:(int)startId end:(int)endId atCharacterOffset:(int)offset
{
NSString *result = [self.js executeJavaScript: Input_positionWithinRangeAtCharacterOffset nargs: 3,
[NSNumber numberWithInt: startId], [NSNumber numberWithInt: endId],
[NSNumber numberWithInt: offset]];
return result.intValue;
}
- (int)characterOffsetOfPosition:(int)positionId withinRangeStart:(int)startId end:(int)endId
{
NSString *result = [self.js executeJavaScript: Input_characterOffsetOfPositionWithinRange nargs: 3,
[NSNumber numberWithInt: positionId],
[NSNumber numberWithInt: startId], [NSNumber numberWithInt: endId]];
return result.intValue;
}
// UITextInputTokenizer methods
- (BOOL)isPosition:(int)posId atBoundary:(NSString *)granularity inDirection:(NSString *)direction
{
NSString *result = [self.js executeJavaScript: Input_isPositionAtBoundaryGranularityInDirection nargs: 3,
[NSNumber numberWithInt: posId], granularity, direction];
return [result isEqualToString: @"true"];
}
- (BOOL)isPosition:(int)posId withinTextUnit:(NSString *)granularity inDirection:(NSString *)direction
{
NSString *result = [self.js executeJavaScript: Input_isPositionWithinTextUnitInDirection nargs: 3,
[NSNumber numberWithInt: posId], granularity, direction];
return [result isEqualToString: @"true"];
}
- (int)positionFromPosition:(int)posId toBoundary:(NSString *)granularity inDirection:(NSString *)direction
{
NSString *result = [self.js executeJavaScript: Input_positionFromPositionToBoundaryInDirection nargs: 3,
[NSNumber numberWithInt: posId], granularity, direction];
return result.intValue;
}
- (NSDictionary *)rangeEnclosingPosition:(int)posId withGranularity:(NSString *)granularity inDirection:(NSString *)direction
{
return [self.js executeJavaScriptJSON: Input_rangeEnclosingPositionWithGranularityInDirection nargs: 3,
[NSNumber numberWithInt: posId], granularity, direction];
}
@end
////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// JSLists //
// //
////////////////////////////////////////////////////////////////////////////////////////////////////
// Functions implemented in Lists.js
@implementation JSLists
- (void)increaseIndent
{
[self.js executeJavaScript: Lists_increaseIndent nargs: 0];
}
- (void)decreaseIndent
{
[self.js executeJavaScript: Lists_decreaseIndent nargs: 0];
}
- (void)clearList
{
[self.js executeJavaScript: Lists_clearList nargs: 0];
}
- (void)setUnorderedList
{
[self.js executeJavaScript: Lists_setUnorderedList nargs: 0];
}
- (void)setOrderedList
{
[self.js executeJavaScript: Lists_setOrderedList nargs: 0];
}
@end
////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// JSMain //
// //
////////////////////////////////////////////////////////////////////////////////////////////////////
// Functions implemented in Main.js
@implementation JSMain
- (NSString *)getLanguage
{
return [self.js executeJavaScript: Main_getLanguage nargs: 0];
}
- (void)setLanguage:(NSString *)language
{
[self.js executeJavaScript: Main_setLanguage nargs: 1, language];
}
- (NSString *)setGenerator:(NSString *)generator
{
return [self.js executeJavaScript: Main_setGenerator nargs: 1, generator];
}
- (BOOL)prepareForSave
{
NSString *result = [self.js executeJavaScript: Main_prepareForSave nargs: 0];
return [@"true" isEqualToString: result];
}
- (NSString *)getHTML;
{
return [self.js executeJavaScript: Main_getHTML nargs: 0];
}
- (BOOL)isEmptyDocument
{
NSString *result = [self.js executeJavaScript: Main_isEmptyDocument nargs: 0];
return [result isEqualToString: @"true"];
}
@end
////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// JSMetadata //
// //
////////////////////////////////////////////////////////////////////////////////////////////////////
@implementation JSMetadata
- (NSDictionary *)getMetadata
{
return [self.js executeJavaScriptJSON: Metadata_getMetadata nargs: 0];
}
- (void)setMetadata:(NSDictionary *)metadata
{
[self.js executeJavaScriptJSON: Metadata_setMetadata nargs: 1, metadata];
}
@end
////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// JSOutline //
// //
////////////////////////////////////////////////////////////////////////////////////////////////////
// Functions implemented in Outline.js
@implementation JSOutline
- (NSDictionary *)getOutline
{
return [self.js executeJavaScriptJSON: Outline_getOutline nargs: 0];
}
- (void)moveSection:(NSString *)sectionId parentId:(NSString *)parentId nextId:(NSString *)nextId
{
[self.js executeJavaScript: Outline_moveSection nargs: 3, sectionId, parentId, nextId];
}
- (void)deleteItem:(NSString *)itemId
{
[self.js executeJavaScript: Outline_deleteItem nargs: 1, itemId];
}
- (void)scheduleUpdateStructure
{
[self.js executeJavaScript: Outline_scheduleUpdateStructure nargs: 0];
}
- (void)goToItem:(NSString *)itemId
{
[self.js executeJavaScript: Outline_goToItem nargs: 1, itemId];
}
- (void)set:(NSString *)itemId numbered:(BOOL)numbered
{
[self.js executeJavaScript: Outline_setNumbered nargs: 2, itemId, [NSNumber numberWithBool: numbered]];
}
- (void)set:(NSString *)itemId title:(NSString *)title
{
[self.js executeJavaScript: Outline_setTitle nargs: 2, itemId, title];
}
- (void)insertTableOfContents
{
[self.js executeJavaScript: Outline_insertTableOfContents nargs: 0];
}
- (void)insertListOfFigures
{
[self.js executeJavaScript: Outline_insertListOfFigures nargs: 0];
}
- (void)insertListOfTables
{
[self.js executeJavaScript: Outline_insertListOfTables nargs: 0];
}
- (void)setPrintMode:(BOOL)printMode
{
[self.js executeJavaScript: Outline_setPrintMode nargs: 1, [NSNumber numberWithBool: printMode]];
}
- (NSDictionary *)examinePrintLayout:(int)pageHeight
{
return [self.js executeJavaScriptJSON: Outline_examinePrintLayout nargs: 1,
[NSNumber numberWithInt: pageHeight]];
}
- (BOOL)detectSectionNumbering
{
NSString *result = [self.js executeJavaScript: Outline_detectSectionNumbering nargs: 0];
return [result isEqualToString: @"true"];
}
- (NSDictionary *)findUsedStyles
{
return [self.js executeJavaScriptJSON: Outline_findUsedStyles nargs: 0];
}
@end
////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// JSPreview //
// //
////////////////////////////////////////////////////////////////////////////////////////////////////
@implementation JSPreview
- (void)showForStyle:(NSString *)styleId uiName:(NSString *)uiName title:(NSString *)title
{
[self.js executeJavaScript: Preview_showForStyle nargs: 3, styleId, uiName, title];
}
@end
////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// JSScan //
// //
////////////////////////////////////////////////////////////////////////////////////////////////////
@implementation JSScan
- (void)reset
{
[self.js executeJavaScript: Scan_reset nargs: 0];
}
- (EDScanParagraph *)next
{
NSDictionary *dict = [self.js executeJavaScriptJSON: Scan_next nargs: 0];
if ((dict == nil) || ![dict isKindOfClass: [NSDictionary class]])
return nil;
NSString *text = FCGetString(dict,@"text",nil);
NSString *sectionId = FCGetString(dict,@"sectionId",nil);
if (text == nil)
return nil;
return [[EDScanParagraph alloc] initWithText: text sectionId: sectionId];
}
- (int)addMatchStart:(int)start end:(int)end
{
return [self.js executeJavaScript: Scan_addMatch nargs: 2,
[NSNumber numberWithInt: start],
[NSNumber numberWithInt: end]].intValue;
}
- (void)showMatch:(int)matchId
{
[self.js executeJavaScript: Scan_showMatch nargs: 1, [NSNumber numberWithInt: matchId]];
}
- (void)replaceMatch:(int)matchId with:(NSString *)text
{
[self.js executeJavaScript: Scan_replaceMatch nargs: 2, [NSNumber numberWithInt: matchId], text];
}
- (void)removeMatch:(int)matchId
{
[self.js executeJavaScript: Scan_removeMatch nargs: 1, [NSNumber numberWithInt: matchId]];
}
- (void)goToMatch:(int)matchId
{
[self.js executeJavaScript: Scan_goToMatch nargs: 1, [NSNumber numberWithInt: matchId]];
}
@end
////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// JSSelection //
// //
////////////////////////////////////////////////////////////////////////////////////////////////////
// Functions implemented in Selection.js
@implementation JSSelection
- (void)update
{
[self.js executeJavaScript: Selection_update nargs: 0];
}
- (void)selectAll
{
[self.js executeJavaScript: Selection_selectAll nargs: 0];
}
- (void)selectParagraph
{
[self.js executeJavaScript: Selection_selectParagraph nargs: 0];
}
- (void)selectWordAtCursor
{
[self.js executeJavaScript: Selection_selectWordAtCursor nargs: 0];
}
- (NSString *)dragSelectionBeginX:(int)x y:(int)y selectWord:(BOOL)selectWord
{
return [self.js executeJavaScript: Selection_dragSelectionBegin nargs: 3,
[NSNumber numberWithInt: x], [NSNumber numberWithInt: y],
[NSNumber numberWithBool: selectWord]];
}
- (NSString *)dragSelectionUpdateX:(int)x y:(int)y selectWord:(BOOL)selectWord
{
return [self.js executeJavaScript: Selection_dragSelectionUpdate nargs: 3,
[NSNumber numberWithInt: x], [NSNumber numberWithInt: y],
[NSNumber numberWithBool: selectWord]];
}
- (NSString *)moveStartLeft
{
return [self.js executeJavaScript: Selection_moveStartLeft nargs: 0];
}
- (NSString *)moveStartRight
{
return [self.js executeJavaScript: Selection_moveStartRight nargs: 0];
}
- (NSString *)moveEndLeft
{
return [self.js executeJavaScript: Selection_moveEndLeft nargs: 0];
}
- (NSString *)moveEndRight
{
return [self.js executeJavaScript: Selection_moveEndRight nargs: 0];
}
- (void)setSelectionStartAtCoordsX:(int)x y:(int)y
{
[self.js executeJavaScript: Selection_setSelectionStartAtCoords nargs: 2,
[NSNumber numberWithInt: x], [NSNumber numberWithInt: y]];
}
- (void)setSelectionEndAtCoordsX:(int)x y:(int)y
{
[self.js executeJavaScript: Selection_setSelectionEndAtCoords nargs: 2,
[NSNumber numberWithInt: x], [NSNumber numberWithInt: y]];
}
- (void)setTableSelectionEdge:(NSString *)edge atCoordsX:(int)x y:(int)y
{
[self.js executeJavaScript: Selection_setTableSelectionEdgeAtCoords nargs: 3,
edge, [NSNumber numberWithInt: x], [NSNumber numberWithInt: y]];
}
- (void)print
{
[self.js executeJavaScript: Selection_print nargs: 0];
}
@end
////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// JSStyles //
// //
////////////////////////////////////////////////////////////////////////////////////////////////////
@implementation JSStyles
- (NSString *)getCSSText
{
return [self.js executeJavaScript: Styles_getCSSText nargs: 0];
}
- (void)setCSSText:(NSString *)cssText rules:(NSDictionary *)rules
{
// debug(@"---------------------- setCSSText ----------------------\n");
// debug(@"%@",cssText);
// if ((cssText.length > 0) && ([cssText characterAtIndex: cssText.length-1] != '\n'))
// debug(@"\n");
// debug(@"--------------------------------------------------------\n");
[self.js executeJavaScriptJSON: Styles_setCSSText nargs: 2, cssText, rules];
}
- (NSString *)paragraphClass
{
return [self.js executeJavaScript: Styles_getParagraphClass nargs: 0];
}
- (void)setParagraphClass:(NSString *)paragraphClass;
{
[self.js executeJavaScript: Styles_setParagraphClass nargs: 1, paragraphClass];
}
@end
////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// JSTables //
// //
////////////////////////////////////////////////////////////////////////////////////////////////////
// Functions implemented in Tables.js
@implementation JSTables
- (void)insertTableRows:(int)rows cols:(int)cols width:(NSString *)width numbered:(BOOL)numbered
caption:(NSString *)caption className:(NSString *)className;
{
[self.js executeJavaScript: Tables_insertTable nargs: 6,
[NSNumber numberWithInt: rows], [NSNumber numberWithInt: cols],
width, [NSNumber numberWithBool: numbered], caption, className];
}
- (void)addAdjacentRow
{
[self.js executeJavaScript: Tables_addAdjacentRow nargs: 0];
}
- (void)addAdjacentColumn
{
[self.js executeJavaScript: Tables_addAdjacentColumn nargs: 0];
}
- (void)removeAdjacentRow
{
[self.js executeJavaScript: Tables_removeAdjacentRow nargs: 0];
}
- (void)removeAdjacentColumn
{
[self.js executeJavaScript: Tables_removeAdjacentColumn nargs: 0];
}
- (void)clearCells
{
[self.js executeJavaScript: Tables_clearCells nargs: 0];
}
- (void)mergeCells
{
[self.js executeJavaScript: Tables_mergeCells nargs: 0];
}
- (void)splitSelection
{
[self.js executeJavaScript: Tables_splitSelection nargs: 0];
}
- (NSString *)getSelectedTableId
{
return [self.js executeJavaScript: Tables_getSelectedTableId nargs: 0];
}
- (NSDictionary *)getProperties:(NSString *)itemId
{
return [self.js executeJavaScriptJSON: Tables_getProperties nargs: 1, itemId];
}
- (void)setProperties:(NSString *)itemId width:(NSString *)width
{
[self.js executeJavaScript: Tables_setProperties nargs: 2, itemId, width];
}
- (void)set:(NSString *)itemId colWidths:(NSArray *)colWidths
{
[self.js executeJavaScript: Tables_setColWidths nargs: 2, itemId, colWidths];
}
- (NSDictionary *)getGeometry:(NSString *)itemId
{
return [self.js executeJavaScriptJSON: Tables_getGeometry nargs: 1, itemId];
}
@end
////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// JSUndoManager //
// //
////////////////////////////////////////////////////////////////////////////////////////////////////
@implementation JSUndoManager
- (int)getLength
{
NSString *result = [self.js executeJavaScript: UndoManager_getLength nargs: 0];
return result.intValue;
}
- (int)getIndex
{
NSString *result = [self.js executeJavaScript: UndoManager_getIndex nargs: 0];
return result.intValue;
}
- (void)setIndex:(int)index
{
[self.js executeJavaScript: UndoManager_setIndex nargs: 1, [NSNumber numberWithInt: index]];
}
- (void)undo
{
[self.js executeJavaScript: UndoManager_undo nargs: 0];
}
- (void)redo
{
[self.js executeJavaScript: UndoManager_redo nargs: 0];
}
- (void)newGroup:(NSString *)name
{
[self.js executeJavaScript: UndoManager_newGroup nargs: 1, name];
}
- (NSString *)groupType
{
return [self.js executeJavaScript: UndoManager_groupType nargs: 0];
}
@end
////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// JSViewport //
// //
////////////////////////////////////////////////////////////////////////////////////////////////////
// Functions implemented in Viewport.js
@implementation JSViewport
- (void)setViewportWidth:(int)width
{
[self.js executeJavaScript: Viewport_setViewportWidth nargs: 1, [NSNumber numberWithInt: width]];
}
- (void)setTextScale:(int)textScale
{
[self.js executeJavaScript: Viewport_setTextScale nargs: 1, [NSNumber numberWithInt: textScale]];
}
@end