| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073 |
- //
- // ZSSRichTextEditorViewController.m
- // ZSSRichTextEditor
- //
- // Created by Nicholas Hubbard on 11/30/13.
- // Copyright (c) 2013 Zed Said Studio. All rights reserved.
- //
- #import <objc/runtime.h>
- #import <UIKit/UIKit.h>
- #import "ZSSRichTextEditor.h"
- #import "ZSSBarButtonItem.h"
- #import "HRColorUtil.h"
- #import "ZSSTextView.h"
- @import JavaScriptCore;
- /**
-
- UIWebView modifications for hiding the inputAccessoryView
-
- **/
- @interface UIWebView (HackishAccessoryHiding)
- @property (nonatomic, assign) BOOL hidesInputAccessoryView;
- @end
- @implementation UIWebView (HackishAccessoryHiding)
- static const char * const hackishFixClassName = "UIWebBrowserViewMinusAccessoryView";
- static Class hackishFixClass = Nil;
- - (UIView *)hackishlyFoundBrowserView {
- UIScrollView *scrollView = self.scrollView;
-
- UIView *browserView = nil;
- for (UIView *subview in scrollView.subviews) {
- if ([NSStringFromClass([subview class]) hasPrefix:@"UIWebBrowserView"]) {
- browserView = subview;
- break;
- }
- }
- return browserView;
- }
- - (id)methodReturningNil {
- return nil;
- }
- - (void)ensureHackishSubclassExistsOfBrowserViewClass:(Class)browserViewClass {
- if (!hackishFixClass) {
- Class newClass = objc_allocateClassPair(browserViewClass, hackishFixClassName, 0);
- newClass = objc_allocateClassPair(browserViewClass, hackishFixClassName, 0);
- IMP nilImp = [self methodForSelector:@selector(methodReturningNil)];
- class_addMethod(newClass, @selector(inputAccessoryView), nilImp, "@@:");
- objc_registerClassPair(newClass);
-
- hackishFixClass = newClass;
- }
- }
- - (BOOL) hidesInputAccessoryView {
- UIView *browserView = [self hackishlyFoundBrowserView];
- return [browserView class] == hackishFixClass;
- }
- - (void) setHidesInputAccessoryView:(BOOL)value {
- UIView *browserView = [self hackishlyFoundBrowserView];
- if (browserView == nil) {
- return;
- }
- [self ensureHackishSubclassExistsOfBrowserViewClass:[browserView class]];
-
- if (value) {
- object_setClass(browserView, hackishFixClass);
- }
- else {
- Class normalClass = objc_getClass("UIWebBrowserView");
- object_setClass(browserView, normalClass);
- }
- [browserView reloadInputViews];
- }
- @end
- @interface ZSSRichTextEditor ()
- /*
- * Scroll view containing the toolbar
- */
- @property (nonatomic, strong) UIScrollView *toolBarScroll;
- /*
- * Toolbar containing ZSSBarButtonItems
- */
- @property (nonatomic, strong) UIToolbar *toolbar;
- /*
- * Holder for all of the toolbar components
- */
- @property (nonatomic, strong) UIView *toolbarHolder;
- /*
- * String for the HTML
- */
- @property (nonatomic, strong) NSString *htmlString;
- /*
- * UIWebView for writing/editing/displaying the content
- */
- @property (nonatomic, strong) UIWebView *editorView;
- /*
- * ZSSTextView for displaying the source code for what is displayed in the editor view
- */
- @property (nonatomic, strong) ZSSTextView *sourceView;
- /*
- * CGRect for holding the frame for the editor view
- */
- @property (nonatomic) CGRect editorViewFrame;
- /*
- * BOOL for holding if the resources are loaded or not
- */
- @property (nonatomic) BOOL resourcesLoaded;
- /*
- * Array holding the enabled editor items
- */
- @property (nonatomic, strong) NSArray *editorItemsEnabled;
- /*
- * Alert View used when inserting links/images
- */
- @property (nonatomic, strong) UIAlertView *alertView;
- /*
- * NSString holding the selected links URL value
- */
- @property (nonatomic, strong) NSString *selectedLinkURL;
- /*
- * NSString holding the selected links title value
- */
- @property (nonatomic, strong) NSString *selectedLinkTitle;
- /*
- * NSString holding the selected image URL value
- */
- @property (nonatomic, strong) NSString *selectedImageURL;
- /*
- * NSString holding the selected image Alt value
- */
- @property (nonatomic, strong) NSString *selectedImageAlt;
- /*
- * CGFloat holdign the selected image scale value
- */
- @property (nonatomic, assign) CGFloat selectedImageScale;
- /*
- * NSString holding the base64 value of the current image
- */
- @property (nonatomic, strong) NSString *imageBase64String;
- /*
- * Bar button item for the keyboard dismiss button in the toolbar
- */
- @property (nonatomic, strong) UIBarButtonItem *keyboardItem;
- /*
- * Array for custom bar button items
- */
- @property (nonatomic, strong) NSMutableArray *customBarButtonItems;
- /*
- * Array for custom ZSSBarButtonItems
- */
- @property (nonatomic, strong) NSMutableArray *customZSSBarButtonItems;
- /*
- * NSString holding the html
- */
- @property (nonatomic, strong) NSString *internalHTML;
- /*
- * NSString holding the css
- */
- @property (nonatomic, strong) NSString *customCSS;
- /*
- * BOOL for if the editor is loaded or not
- */
- @property (nonatomic) BOOL editorLoaded;
- /*
- * Image Picker for selecting photos from users photo library
- */
- @property (nonatomic, strong) UIImagePickerController *imagePicker;
- /*
- * Method for getting a version of the html without quotes
- */
- - (NSString *)removeQuotesFromHTML:(NSString *)html;
- /*
- * Method for getting a tidied version of the html
- */
- - (NSString *)tidyHTML:(NSString *)html;
- /*
- * Method for enablign toolbar items
- */
- - (void)enableToolbarItems:(BOOL)enable;
- /*
- * Setter for isIpad BOOL
- */
- - (BOOL)isIpad;
- @end
- /*
-
- ZSSRichTextEditor
-
- */
- @implementation ZSSRichTextEditor
- //Scale image from device
- static CGFloat kJPEGCompression = 0.8;
- static CGFloat kDefaultScale = 0.3;
- #pragma mark - View Did Load Section
- - (void)viewDidLoad {
-
- [super viewDidLoad];
-
- //Initialise variables
- self.editorLoaded = NO;
- self.receiveEditorDidChangeEvents = NO;
- self.alwaysShowToolbar = NO;
- self.shouldShowKeyboard = YES;
- self.formatHTML = YES;
-
- //Initalise enabled toolbar items array
- self.enabledToolbarItems = [[NSArray alloc] init];
-
- //Frame for the source view and editor view
- CGRect frame = CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height);
-
- //Source View
- [self createSourceViewWithFrame:frame];
-
- //Editor View
- [self createEditorViewWithFrame:frame];
-
- //Image Picker used to allow the user insert images from the device (base64 encoded)
- [self setUpImagePicker];
-
- //Scrolling View
- [self createToolBarScroll];
-
- //Toolbar with icons
- [self createToolbar];
-
- //Parent holding view
- [self createParentHoldingView];
-
- //Hide Keyboard
- if (![self isIpad]) {
-
- // Toolbar holder used to crop and position toolbar
- UIView *toolbarCropper = [[UIView alloc] initWithFrame:CGRectMake(self.view.frame.size.width-44, 0, 44, 44)];
- toolbarCropper.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin;
- toolbarCropper.clipsToBounds = YES;
-
- // Use a toolbar so that we can tint
- UIToolbar *keyboardToolbar = [[UIToolbar alloc] initWithFrame:CGRectMake(-7, -1, 44, 44)];
- [toolbarCropper addSubview:keyboardToolbar];
-
- self.keyboardItem = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"ZSSkeyboard.png"] style:UIBarButtonItemStylePlain target:self action:@selector(dismissKeyboard)];
- keyboardToolbar.items = @[self.keyboardItem];
- [self.toolbarHolder addSubview:toolbarCropper];
-
- UIView *line = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 0.6f, 44)];
- line.backgroundColor = [UIColor lightGrayColor];
- line.alpha = 0.7f;
- [toolbarCropper addSubview:line];
-
- }
-
- [self.view addSubview:self.toolbarHolder];
-
- //Build the toolbar
- [self buildToolbar];
-
- //Load Resources
- if (!self.resourcesLoaded) {
-
- [self loadResources];
-
- }
-
- }
- #pragma mark - View Will Appear Section
- - (void)viewWillAppear:(BOOL)animated {
-
- [super viewWillAppear:animated];
-
- //Add observers for keyboard showing or hiding notifications
- [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShowOrHide:) name:UIKeyboardWillShowNotification object:nil];
- [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShowOrHide:) name:UIKeyboardWillHideNotification object:nil];
- }
- #pragma mark - View Will Disappear Section
- - (void)viewWillDisappear:(BOOL)animated {
-
- [super viewWillDisappear:animated];
-
- //Remove observers for keyboard showing or hiding notifications
- [[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillShowNotification object:nil];
- [[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillHideNotification object:nil];
-
- }
- #pragma mark - Set Up View Section
- - (void)createSourceViewWithFrame:(CGRect)frame {
-
- self.sourceView = [[ZSSTextView alloc] initWithFrame:frame];
- self.sourceView.hidden = YES;
- self.sourceView.autocapitalizationType = UITextAutocapitalizationTypeNone;
- self.sourceView.autocorrectionType = UITextAutocorrectionTypeNo;
- self.sourceView.font = [UIFont fontWithName:@"Courier" size:13.0];
- self.sourceView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
- self.sourceView.autoresizesSubviews = YES;
- self.sourceView.delegate = self;
- [self.view addSubview:self.sourceView];
-
- }
- - (void)createEditorViewWithFrame:(CGRect)frame {
-
- self.editorView = [[UIWebView alloc] initWithFrame:frame];
- self.editorView.delegate = self;
- self.editorView.hidesInputAccessoryView = YES;
- self.editorView.keyboardDisplayRequiresUserAction = NO;
- self.editorView.scalesPageToFit = YES;
- self.editorView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleBottomMargin;
- self.editorView.dataDetectorTypes = UIDataDetectorTypeNone;
- self.editorView.scrollView.bounces = NO;
- self.editorView.backgroundColor = [UIColor whiteColor];
- [self.view addSubview:self.editorView];
-
- }
- - (void)setUpImagePicker {
-
- self.imagePicker = [[UIImagePickerController alloc] init];
- self.imagePicker.delegate = self;
- self.imagePicker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
- self.imagePicker.allowsEditing = YES;
- self.selectedImageScale = kDefaultScale; //by default scale to half the size
-
- }
- - (void)createToolBarScroll {
-
- self.toolBarScroll = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, [self isIpad] ? self.view.frame.size.width : self.view.frame.size.width - 44, 44)];
- self.toolBarScroll.backgroundColor = [UIColor clearColor];
- self.toolBarScroll.showsHorizontalScrollIndicator = NO;
-
- }
- - (void)createToolbar {
-
- self.toolbar = [[UIToolbar alloc] initWithFrame:CGRectZero];
- self.toolbar.autoresizingMask = UIViewAutoresizingFlexibleWidth;
- self.toolbar.backgroundColor = [UIColor clearColor];
- [self.toolBarScroll addSubview:self.toolbar];
- self.toolBarScroll.autoresizingMask = self.toolbar.autoresizingMask;
-
- }
- - (void)createParentHoldingView {
-
- //Background Toolbar
- UIToolbar *backgroundToolbar = [[UIToolbar alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, 44)];
- backgroundToolbar.autoresizingMask = UIViewAutoresizingFlexibleWidth;
-
- //Parent holding view
- self.toolbarHolder = [[UIView alloc] init];
-
- if (_alwaysShowToolbar) {
- self.toolbarHolder.frame = CGRectMake(0, self.view.frame.size.height - 44, self.view.frame.size.width, 44);
- } else {
- self.toolbarHolder.frame = CGRectMake(0, self.view.frame.size.height, self.view.frame.size.width, 44);
- }
-
- self.toolbarHolder.autoresizingMask = self.toolbar.autoresizingMask;
- [self.toolbarHolder addSubview:self.toolBarScroll];
- [self.toolbarHolder insertSubview:backgroundToolbar atIndex:0];
-
- }
- #pragma mark - Resources Section
- - (void)loadResources {
-
- //Create a string with the contents of editor.html
- NSString *filePath = [[NSBundle mainBundle] pathForResource:@"editor" ofType:@"html"];
- NSData *htmlData = [NSData dataWithContentsOfFile:filePath];
- NSString *htmlString = [[NSString alloc] initWithData:htmlData encoding:NSUTF8StringEncoding];
-
- //Add jQuery.js to the html file
- NSString *jquery = [[NSBundle mainBundle] pathForResource:@"jQuery" ofType:@"js"];
- NSString *jqueryString = [[NSString alloc] initWithData:[NSData dataWithContentsOfFile:jquery] encoding:NSUTF8StringEncoding];
- htmlString = [htmlString stringByReplacingOccurrencesOfString:@"<!-- jQuery -->" withString:jqueryString];
-
- //Add JSBeautifier.js to the html file
- NSString *beautifier = [[NSBundle mainBundle] pathForResource:@"JSBeautifier" ofType:@"js"];
- NSString *beautifierString = [[NSString alloc] initWithData:[NSData dataWithContentsOfFile:beautifier] encoding:NSUTF8StringEncoding];
- htmlString = [htmlString stringByReplacingOccurrencesOfString:@"<!-- jsbeautifier -->" withString:beautifierString];
-
- //Add ZSSRichTextEditor.js to the html file
- NSString *source = [[NSBundle mainBundle] pathForResource:@"ZSSRichTextEditor" ofType:@"js"];
- NSString *jsString = [[NSString alloc] initWithData:[NSData dataWithContentsOfFile:source] encoding:NSUTF8StringEncoding];
- htmlString = [htmlString stringByReplacingOccurrencesOfString:@"<!--editor-->" withString:jsString];
-
- [self.editorView loadHTMLString:htmlString baseURL:self.baseURL];
- self.resourcesLoaded = YES;
-
- }
- #pragma mark - Toolbar Section
- - (void)setEnabledToolbarItems:(NSArray *)enabledToolbarItems {
-
- _enabledToolbarItems = enabledToolbarItems;
- [self buildToolbar];
-
- }
- - (void)setToolbarItemTintColor:(UIColor *)toolbarItemTintColor {
-
- _toolbarItemTintColor = toolbarItemTintColor;
-
- // Update the color
- for (ZSSBarButtonItem *item in self.toolbar.items) {
- item.tintColor = [self barButtonItemDefaultColor];
- }
- self.keyboardItem.tintColor = toolbarItemTintColor;
-
- }
- - (void)setToolbarItemSelectedTintColor:(UIColor *)toolbarItemSelectedTintColor {
-
- _toolbarItemSelectedTintColor = toolbarItemSelectedTintColor;
-
- }
- - (NSArray *)itemsForToolbar {
-
- NSMutableArray *items = [[NSMutableArray alloc] init];
-
- // None
- if(_enabledToolbarItems && [_enabledToolbarItems containsObject:ZSSRichTextEditorToolbarNone])
- {
- return items;
- }
-
- BOOL customOrder = NO;
- if (_enabledToolbarItems && ![_enabledToolbarItems containsObject:ZSSRichTextEditorToolbarAll]){
- customOrder = YES;
- for(int i=0; i < _enabledToolbarItems.count;i++){
- [items addObject:@""];
- }
- }
-
- // Bold
- if ((_enabledToolbarItems && [_enabledToolbarItems containsObject:ZSSRichTextEditorToolbarBold]) || (_enabledToolbarItems && [_enabledToolbarItems containsObject:ZSSRichTextEditorToolbarAll])) {
- ZSSBarButtonItem *bold = [[ZSSBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"ZSSbold.png"] style:UIBarButtonItemStylePlain target:self action:@selector(setBold)];
- bold.label = @"bold";
- if (customOrder) {
- [items replaceObjectAtIndex:[_enabledToolbarItems indexOfObject:ZSSRichTextEditorToolbarBold] withObject:bold];
- } else {
- [items addObject:bold];
- }
- }
-
- // Italic
- if ((_enabledToolbarItems && [_enabledToolbarItems containsObject:ZSSRichTextEditorToolbarItalic]) || (_enabledToolbarItems && [_enabledToolbarItems containsObject:ZSSRichTextEditorToolbarAll])) {
- ZSSBarButtonItem *italic = [[ZSSBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"ZSSitalic.png"] style:UIBarButtonItemStylePlain target:self action:@selector(setItalic)];
- italic.label = @"italic";
- if (customOrder) {
- [items replaceObjectAtIndex:[_enabledToolbarItems indexOfObject:ZSSRichTextEditorToolbarItalic] withObject:italic];
- } else {
- [items addObject:italic];
- }
- }
-
- // Subscript
- if ((_enabledToolbarItems && [_enabledToolbarItems containsObject:ZSSRichTextEditorToolbarSubscript]) || (_enabledToolbarItems && [_enabledToolbarItems containsObject:ZSSRichTextEditorToolbarAll])) {
- ZSSBarButtonItem *subscript = [[ZSSBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"ZSSsubscript.png"] style:UIBarButtonItemStylePlain target:self action:@selector(setSubscript)];
- subscript.label = @"subscript";
- if (customOrder) {
- [items replaceObjectAtIndex:[_enabledToolbarItems indexOfObject:ZSSRichTextEditorToolbarSubscript] withObject:subscript];
- } else {
- [items addObject:subscript];
- }
- }
-
- // Superscript
- if ((_enabledToolbarItems && [_enabledToolbarItems containsObject:ZSSRichTextEditorToolbarSuperscript]) || (_enabledToolbarItems && [_enabledToolbarItems containsObject:ZSSRichTextEditorToolbarAll])) {
- ZSSBarButtonItem *superscript = [[ZSSBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"ZSSsuperscript.png"] style:UIBarButtonItemStylePlain target:self action:@selector(setSuperscript)];
- superscript.label = @"superscript";
- if (customOrder) {
- [items replaceObjectAtIndex:[_enabledToolbarItems indexOfObject:ZSSRichTextEditorToolbarSuperscript] withObject:superscript];
- } else {
- [items addObject:superscript];
- }
- }
-
- // Strike Through
- if ((_enabledToolbarItems && [_enabledToolbarItems containsObject:ZSSRichTextEditorToolbarStrikeThrough]) || (_enabledToolbarItems && [_enabledToolbarItems containsObject:ZSSRichTextEditorToolbarAll])) {
- ZSSBarButtonItem *strikeThrough = [[ZSSBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"ZSSstrikethrough.png"] style:UIBarButtonItemStylePlain target:self action:@selector(setStrikethrough)];
- strikeThrough.label = @"strikeThrough";
- if (customOrder) {
- [items replaceObjectAtIndex:[_enabledToolbarItems indexOfObject:ZSSRichTextEditorToolbarStrikeThrough] withObject:strikeThrough];
- } else {
- [items addObject:strikeThrough];
- }
- }
-
- // Underline
- if ((_enabledToolbarItems && [_enabledToolbarItems containsObject:ZSSRichTextEditorToolbarUnderline]) || (_enabledToolbarItems && [_enabledToolbarItems containsObject:ZSSRichTextEditorToolbarAll])) {
- ZSSBarButtonItem *underline = [[ZSSBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"ZSSunderline.png"] style:UIBarButtonItemStylePlain target:self action:@selector(setUnderline)];
- underline.label = @"underline";
- if (customOrder) {
- [items replaceObjectAtIndex:[_enabledToolbarItems indexOfObject:ZSSRichTextEditorToolbarUnderline] withObject:underline];
- } else {
- [items addObject:underline];
- }
- }
-
- // Remove Format
- if ((_enabledToolbarItems && [_enabledToolbarItems containsObject:ZSSRichTextEditorToolbarRemoveFormat]) || (_enabledToolbarItems && [_enabledToolbarItems containsObject:ZSSRichTextEditorToolbarAll])) {
- ZSSBarButtonItem *removeFormat = [[ZSSBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"ZSSclearstyle.png"] style:UIBarButtonItemStylePlain target:self action:@selector(removeFormat)];
- removeFormat.label = @"removeFormat";
- if (customOrder) {
- [items replaceObjectAtIndex:[_enabledToolbarItems indexOfObject:ZSSRichTextEditorToolbarRemoveFormat] withObject:removeFormat];
- } else {
- [items addObject:removeFormat];
- }
- }
-
- // Fonts
- if ((_enabledToolbarItems && [_enabledToolbarItems containsObject:ZSSRichTextEditorToolbarFonts]) || (_enabledToolbarItems && [_enabledToolbarItems containsObject:ZSSRichTextEditorToolbarAll])) {
-
- ZSSBarButtonItem *fonts = [[ZSSBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"ZSSfonts.png"] style:UIBarButtonItemStylePlain target:self action:@selector(showFontsPicker)];
- fonts.label = @"fonts";
- if (customOrder) {
- [items replaceObjectAtIndex:[_enabledToolbarItems indexOfObject:ZSSRichTextEditorToolbarFonts] withObject:fonts];
- } else {
- [items addObject:fonts];
- }
-
- }
-
- // Undo
- if ((_enabledToolbarItems && [_enabledToolbarItems containsObject:ZSSRichTextEditorToolbarUndo]) || (_enabledToolbarItems && [_enabledToolbarItems containsObject:ZSSRichTextEditorToolbarAll])) {
- ZSSBarButtonItem *undoButton = [[ZSSBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"ZSSundo.png"] style:UIBarButtonItemStylePlain target:self action:@selector(undo:)];
- undoButton.label = @"undo";
- if (customOrder) {
- [items replaceObjectAtIndex:[_enabledToolbarItems indexOfObject:ZSSRichTextEditorToolbarUndo] withObject:undoButton];
- } else {
- [items addObject:undoButton];
- }
- }
-
- // Redo
- if ((_enabledToolbarItems && [_enabledToolbarItems containsObject:ZSSRichTextEditorToolbarRedo]) || (_enabledToolbarItems && [_enabledToolbarItems containsObject:ZSSRichTextEditorToolbarAll])) {
- ZSSBarButtonItem *redoButton = [[ZSSBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"ZSSredo.png"] style:UIBarButtonItemStylePlain target:self action:@selector(redo:)];
- redoButton.label = @"redo";
- if (customOrder) {
- [items replaceObjectAtIndex:[_enabledToolbarItems indexOfObject:ZSSRichTextEditorToolbarRedo] withObject:redoButton];
- } else {
- [items addObject:redoButton];
- }
- }
-
- // Align Left
- if ((_enabledToolbarItems && [_enabledToolbarItems containsObject:ZSSRichTextEditorToolbarJustifyLeft]) || (_enabledToolbarItems && [_enabledToolbarItems containsObject:ZSSRichTextEditorToolbarAll])) {
- ZSSBarButtonItem *alignLeft = [[ZSSBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"ZSSleftjustify.png"] style:UIBarButtonItemStylePlain target:self action:@selector(alignLeft)];
- alignLeft.label = @"justifyLeft";
- if (customOrder) {
- [items replaceObjectAtIndex:[_enabledToolbarItems indexOfObject:ZSSRichTextEditorToolbarJustifyLeft] withObject:alignLeft];
- } else {
- [items addObject:alignLeft];
- }
- }
-
- // Align Center
- if ((_enabledToolbarItems && [_enabledToolbarItems containsObject:ZSSRichTextEditorToolbarJustifyCenter]) || (_enabledToolbarItems && [_enabledToolbarItems containsObject:ZSSRichTextEditorToolbarAll])) {
- ZSSBarButtonItem *alignCenter = [[ZSSBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"ZSScenterjustify.png"] style:UIBarButtonItemStylePlain target:self action:@selector(alignCenter)];
- alignCenter.label = @"justifyCenter";
- if (customOrder) {
- [items replaceObjectAtIndex:[_enabledToolbarItems indexOfObject:ZSSRichTextEditorToolbarJustifyCenter] withObject:alignCenter];
- } else {
- [items addObject:alignCenter];
- }
- }
-
- // Align Right
- if ((_enabledToolbarItems && [_enabledToolbarItems containsObject:ZSSRichTextEditorToolbarJustifyRight]) || (_enabledToolbarItems && [_enabledToolbarItems containsObject:ZSSRichTextEditorToolbarAll])) {
- ZSSBarButtonItem *alignRight = [[ZSSBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"ZSSrightjustify.png"] style:UIBarButtonItemStylePlain target:self action:@selector(alignRight)];
- alignRight.label = @"justifyRight";
- if (customOrder) {
- [items replaceObjectAtIndex:[_enabledToolbarItems indexOfObject:ZSSRichTextEditorToolbarJustifyRight] withObject:alignRight];
- } else {
- [items addObject:alignRight];
- }
- }
-
- // Align Justify
- if ((_enabledToolbarItems && [_enabledToolbarItems containsObject:ZSSRichTextEditorToolbarJustifyFull]) || (_enabledToolbarItems && [_enabledToolbarItems containsObject:ZSSRichTextEditorToolbarAll])) {
- ZSSBarButtonItem *alignFull = [[ZSSBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"ZSSforcejustify.png"] style:UIBarButtonItemStylePlain target:self action:@selector(alignFull)];
- alignFull.label = @"justifyFull";
- if (customOrder) {
- [items replaceObjectAtIndex:[_enabledToolbarItems indexOfObject:ZSSRichTextEditorToolbarJustifyFull] withObject:alignFull];
- } else {
- [items addObject:alignFull];
- }
- }
-
- // Paragraph
- if ((_enabledToolbarItems && [_enabledToolbarItems containsObject:ZSSRichTextEditorToolbarParagraph]) || (_enabledToolbarItems && [_enabledToolbarItems containsObject:ZSSRichTextEditorToolbarAll])) {
- ZSSBarButtonItem *paragraph = [[ZSSBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"ZSSparagraph.png"] style:UIBarButtonItemStylePlain target:self action:@selector(paragraph)];
- paragraph.label = @"p";
- if (customOrder) {
- [items replaceObjectAtIndex:[_enabledToolbarItems indexOfObject:ZSSRichTextEditorToolbarParagraph] withObject:paragraph];
- } else {
- [items addObject:paragraph];
- }
- }
-
- // Header 1
- if ((_enabledToolbarItems && [_enabledToolbarItems containsObject:ZSSRichTextEditorToolbarH1]) || (_enabledToolbarItems && [_enabledToolbarItems containsObject:ZSSRichTextEditorToolbarAll])) {
- ZSSBarButtonItem *h1 = [[ZSSBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"ZSSh1.png"] style:UIBarButtonItemStylePlain target:self action:@selector(heading1)];
- h1.label = @"h1";
- if (customOrder) {
- [items replaceObjectAtIndex:[_enabledToolbarItems indexOfObject:ZSSRichTextEditorToolbarH1] withObject:h1];
- } else {
- [items addObject:h1];
- }
- }
-
- // Header 2
- if ((_enabledToolbarItems && [_enabledToolbarItems containsObject:ZSSRichTextEditorToolbarH2]) || (_enabledToolbarItems && [_enabledToolbarItems containsObject:ZSSRichTextEditorToolbarAll])) {
- ZSSBarButtonItem *h2 = [[ZSSBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"ZSSh2.png"] style:UIBarButtonItemStylePlain target:self action:@selector(heading2)];
- h2.label = @"h2";
- if (customOrder) {
- [items replaceObjectAtIndex:[_enabledToolbarItems indexOfObject:ZSSRichTextEditorToolbarH2] withObject:h2];
- } else {
- [items addObject:h2];
- }
- }
-
- // Header 3
- if ((_enabledToolbarItems && [_enabledToolbarItems containsObject:ZSSRichTextEditorToolbarH3]) || (_enabledToolbarItems && [_enabledToolbarItems containsObject:ZSSRichTextEditorToolbarAll])) {
- ZSSBarButtonItem *h3 = [[ZSSBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"ZSSh3.png"] style:UIBarButtonItemStylePlain target:self action:@selector(heading3)];
- h3.label = @"h3";
- if (customOrder) {
- [items replaceObjectAtIndex:[_enabledToolbarItems indexOfObject:ZSSRichTextEditorToolbarH3] withObject:h3];
- } else {
- [items addObject:h3];
- }
- }
-
- // Heading 4
- if ((_enabledToolbarItems && [_enabledToolbarItems containsObject:ZSSRichTextEditorToolbarH4]) || (_enabledToolbarItems && [_enabledToolbarItems containsObject:ZSSRichTextEditorToolbarAll])) {
- ZSSBarButtonItem *h4 = [[ZSSBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"ZSSh4.png"] style:UIBarButtonItemStylePlain target:self action:@selector(heading4)];
- h4.label = @"h4";
- if (customOrder) {
- [items replaceObjectAtIndex:[_enabledToolbarItems indexOfObject:ZSSRichTextEditorToolbarH4] withObject:h4];
- } else {
- [items addObject:h4];
- }
- }
-
- // Header 5
- if ((_enabledToolbarItems && [_enabledToolbarItems containsObject:ZSSRichTextEditorToolbarH5]) || (_enabledToolbarItems && [_enabledToolbarItems containsObject:ZSSRichTextEditorToolbarAll])) {
- ZSSBarButtonItem *h5 = [[ZSSBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"ZSSh5.png"] style:UIBarButtonItemStylePlain target:self action:@selector(heading5)];
- h5.label = @"h5";
- if (customOrder) {
- [items replaceObjectAtIndex:[_enabledToolbarItems indexOfObject:ZSSRichTextEditorToolbarH5] withObject:h5];
- } else {
- [items addObject:h5];
- }
- }
-
- // Heading 6
- if ((_enabledToolbarItems && [_enabledToolbarItems containsObject:ZSSRichTextEditorToolbarH6]) || (_enabledToolbarItems && [_enabledToolbarItems containsObject:ZSSRichTextEditorToolbarAll])) {
- ZSSBarButtonItem *h6 = [[ZSSBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"ZSSh6.png"] style:UIBarButtonItemStylePlain target:self action:@selector(heading6)];
- h6.label = @"h6";
- if (customOrder) {
- [items replaceObjectAtIndex:[_enabledToolbarItems indexOfObject:ZSSRichTextEditorToolbarH6] withObject:h6];
- } else {
- [items addObject:h6];
- }
- }
-
- // Text Color
- if ((_enabledToolbarItems && [_enabledToolbarItems containsObject:ZSSRichTextEditorToolbarTextColor]) || (_enabledToolbarItems && [_enabledToolbarItems containsObject:ZSSRichTextEditorToolbarAll])) {
- ZSSBarButtonItem *textColor = [[ZSSBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"ZSStextcolor.png"] style:UIBarButtonItemStylePlain target:self action:@selector(textColor)];
- textColor.label = @"textColor";
- if (customOrder) {
- [items replaceObjectAtIndex:[_enabledToolbarItems indexOfObject:ZSSRichTextEditorToolbarTextColor] withObject:textColor];
- } else {
- [items addObject:textColor];
- }
- }
-
- // Background Color
- if ((_enabledToolbarItems && [_enabledToolbarItems containsObject:ZSSRichTextEditorToolbarBackgroundColor]) || (_enabledToolbarItems && [_enabledToolbarItems containsObject:ZSSRichTextEditorToolbarAll])) {
- ZSSBarButtonItem *bgColor = [[ZSSBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"ZSSbgcolor.png"] style:UIBarButtonItemStylePlain target:self action:@selector(bgColor)];
- bgColor.label = @"backgroundColor";
- if (customOrder) {
- [items replaceObjectAtIndex:[_enabledToolbarItems indexOfObject:ZSSRichTextEditorToolbarBackgroundColor] withObject:bgColor];
- } else {
- [items addObject:bgColor];
- }
- }
-
- // Unordered List
- if ((_enabledToolbarItems && [_enabledToolbarItems containsObject:ZSSRichTextEditorToolbarUnorderedList]) || (_enabledToolbarItems && [_enabledToolbarItems containsObject:ZSSRichTextEditorToolbarAll])) {
- ZSSBarButtonItem *ul = [[ZSSBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"ZSSunorderedlist.png"] style:UIBarButtonItemStylePlain target:self action:@selector(setUnorderedList)];
- ul.label = @"unorderedList";
- if (customOrder) {
- [items replaceObjectAtIndex:[_enabledToolbarItems indexOfObject:ZSSRichTextEditorToolbarUnorderedList] withObject:ul];
- } else {
- [items addObject:ul];
- }
- }
-
- // Ordered List
- if ((_enabledToolbarItems && [_enabledToolbarItems containsObject:ZSSRichTextEditorToolbarOrderedList]) || (_enabledToolbarItems && [_enabledToolbarItems containsObject:ZSSRichTextEditorToolbarAll])) {
- ZSSBarButtonItem *ol = [[ZSSBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"ZSSorderedlist.png"] style:UIBarButtonItemStylePlain target:self action:@selector(setOrderedList)];
- ol.label = @"orderedList";
- if (customOrder) {
- [items replaceObjectAtIndex:[_enabledToolbarItems indexOfObject:ZSSRichTextEditorToolbarOrderedList] withObject:ol];
- } else {
- [items addObject:ol];
- }
- }
-
- // Horizontal Rule
- if ((_enabledToolbarItems && [_enabledToolbarItems containsObject:ZSSRichTextEditorToolbarHorizontalRule]) || (_enabledToolbarItems && [_enabledToolbarItems containsObject:ZSSRichTextEditorToolbarAll])) {
- ZSSBarButtonItem *hr = [[ZSSBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"ZSShorizontalrule.png"] style:UIBarButtonItemStylePlain target:self action:@selector(setHR)];
- hr.label = @"horizontalRule";
- if (customOrder) {
- [items replaceObjectAtIndex:[_enabledToolbarItems indexOfObject:ZSSRichTextEditorToolbarHorizontalRule] withObject:hr];
- } else {
- [items addObject:hr];
- }
- }
-
- // Indent
- if ((_enabledToolbarItems && [_enabledToolbarItems containsObject:ZSSRichTextEditorToolbarIndent]) || (_enabledToolbarItems && [_enabledToolbarItems containsObject:ZSSRichTextEditorToolbarAll])) {
- ZSSBarButtonItem *indent = [[ZSSBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"ZSSindent.png"] style:UIBarButtonItemStylePlain target:self action:@selector(setIndent)];
- indent.label = @"indent";
- if (customOrder) {
- [items replaceObjectAtIndex:[_enabledToolbarItems indexOfObject:ZSSRichTextEditorToolbarIndent] withObject:indent];
- } else {
- [items addObject:indent];
- }
- }
-
- // Outdent
- if ((_enabledToolbarItems && [_enabledToolbarItems containsObject:ZSSRichTextEditorToolbarOutdent]) || (_enabledToolbarItems && [_enabledToolbarItems containsObject:ZSSRichTextEditorToolbarAll])) {
- ZSSBarButtonItem *outdent = [[ZSSBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"ZSSoutdent.png"] style:UIBarButtonItemStylePlain target:self action:@selector(setOutdent)];
- outdent.label = @"outdent";
- if (customOrder) {
- [items replaceObjectAtIndex:[_enabledToolbarItems indexOfObject:ZSSRichTextEditorToolbarOutdent] withObject:outdent];
- } else {
- [items addObject:outdent];
- }
- }
-
- // Image
- if ((_enabledToolbarItems && [_enabledToolbarItems containsObject:ZSSRichTextEditorToolbarInsertImage]) || (_enabledToolbarItems && [_enabledToolbarItems containsObject:ZSSRichTextEditorToolbarAll])) {
- ZSSBarButtonItem *insertImage = [[ZSSBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"ZSSimage.png"] style:UIBarButtonItemStylePlain target:self action:@selector(insertImage)];
- insertImage.label = @"image";
- if (customOrder) {
- [items replaceObjectAtIndex:[_enabledToolbarItems indexOfObject:ZSSRichTextEditorToolbarInsertImage] withObject:insertImage];
- } else {
- [items addObject:insertImage];
- }
- }
-
- // Image From Device
- if ((_enabledToolbarItems && [_enabledToolbarItems containsObject:ZSSRichTextEditorToolbarInsertImageFromDevice]) || (_enabledToolbarItems && [_enabledToolbarItems containsObject:ZSSRichTextEditorToolbarAll])) {
- ZSSBarButtonItem *insertImageFromDevice = [[ZSSBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"ZSSimageDevice.png"] style:UIBarButtonItemStylePlain target:self action:@selector(insertImageFromDevice)];
- insertImageFromDevice.label = @"imageFromDevice";
- if (customOrder) {
- [items replaceObjectAtIndex:[_enabledToolbarItems indexOfObject:ZSSRichTextEditorToolbarInsertImageFromDevice] withObject:insertImageFromDevice];
- } else {
- [items addObject:insertImageFromDevice];
- }
- }
-
- // Insert Link
- if ((_enabledToolbarItems && [_enabledToolbarItems containsObject:ZSSRichTextEditorToolbarInsertLink]) || (_enabledToolbarItems && [_enabledToolbarItems containsObject:ZSSRichTextEditorToolbarAll])) {
- ZSSBarButtonItem *insertLink = [[ZSSBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"ZSSlink.png"] style:UIBarButtonItemStylePlain target:self action:@selector(insertLink)];
- insertLink.label = @"link";
- if (customOrder) {
- [items replaceObjectAtIndex:[_enabledToolbarItems indexOfObject:ZSSRichTextEditorToolbarInsertLink] withObject:insertLink];
- } else {
- [items addObject:insertLink];
- }
- }
-
- // Remove Link
- if ((_enabledToolbarItems && [_enabledToolbarItems containsObject:ZSSRichTextEditorToolbarRemoveLink]) || (_enabledToolbarItems && [_enabledToolbarItems containsObject:ZSSRichTextEditorToolbarAll])) {
- ZSSBarButtonItem *removeLink = [[ZSSBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"ZSSunlink.png"] style:UIBarButtonItemStylePlain target:self action:@selector(removeLink)];
- removeLink.label = @"removeLink";
- if (customOrder) {
- [items replaceObjectAtIndex:[_enabledToolbarItems indexOfObject:ZSSRichTextEditorToolbarRemoveLink] withObject:removeLink];
- } else {
- [items addObject:removeLink];
- }
- }
-
- // Quick Link
- if ((_enabledToolbarItems && [_enabledToolbarItems containsObject:ZSSRichTextEditorToolbarQuickLink]) || (_enabledToolbarItems && [_enabledToolbarItems containsObject:ZSSRichTextEditorToolbarAll])) {
- ZSSBarButtonItem *quickLink = [[ZSSBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"ZSSquicklink.png"] style:UIBarButtonItemStylePlain target:self action:@selector(quickLink)];
- quickLink.label = @"quickLink";
- if (customOrder) {
- [items replaceObjectAtIndex:[_enabledToolbarItems indexOfObject:ZSSRichTextEditorToolbarQuickLink] withObject:quickLink];
- } else {
- [items addObject:quickLink];
- }
- }
-
- // Show Source
- if ((_enabledToolbarItems && [_enabledToolbarItems containsObject:ZSSRichTextEditorToolbarViewSource]) || (_enabledToolbarItems && [_enabledToolbarItems containsObject:ZSSRichTextEditorToolbarAll])) {
- ZSSBarButtonItem *showSource = [[ZSSBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"ZSSviewsource.png"] style:UIBarButtonItemStylePlain target:self action:@selector(showHTMLSource:)];
- showSource.label = @"source";
- if (customOrder) {
- [items replaceObjectAtIndex:[_enabledToolbarItems indexOfObject:ZSSRichTextEditorToolbarViewSource] withObject:showSource];
- } else {
- [items addObject:showSource];
- }
- }
-
- return [NSArray arrayWithArray:items];
-
- }
- - (void)buildToolbar {
-
- // Check to see if we have any toolbar items, if not, add them all
- NSArray *items = [self itemsForToolbar];
- if (items.count == 0 && !(_enabledToolbarItems && [_enabledToolbarItems containsObject:ZSSRichTextEditorToolbarNone])) {
- _enabledToolbarItems = @[ZSSRichTextEditorToolbarAll];
- items = [self itemsForToolbar];
- }
-
- if (self.customZSSBarButtonItems != nil) {
- items = [items arrayByAddingObjectsFromArray:self.customZSSBarButtonItems];
- }
-
- // get the width before we add custom buttons
- CGFloat toolbarWidth = items.count == 0 ? 0.0f : (CGFloat)(items.count * 39) - 10;
-
- if(self.customBarButtonItems != nil)
- {
- items = [items arrayByAddingObjectsFromArray:self.customBarButtonItems];
- for(ZSSBarButtonItem *buttonItem in self.customBarButtonItems)
- {
- toolbarWidth += buttonItem.customView.frame.size.width + 11.0f;
- }
- }
-
- self.toolbar.items = items;
- for (ZSSBarButtonItem *item in items) {
- item.tintColor = [self barButtonItemDefaultColor];
- }
-
- self.toolbar.frame = CGRectMake(0, 0, toolbarWidth, 44);
- self.toolBarScroll.contentSize = CGSizeMake(self.toolbar.frame.size.width, 44);
- }
- #pragma mark - Editor Modification Section
- - (void)setCSS:(NSString *)css {
-
- self.customCSS = css;
-
- if (self.editorLoaded) {
- [self updateCSS];
- }
-
- }
- - (void)updateCSS {
-
- if (self.customCSS != NULL && [self.customCSS length] != 0) {
-
- NSString *js = [NSString stringWithFormat:@"zss_editor.setCustomCSS(\"%@\");", self.customCSS];
- [self.editorView stringByEvaluatingJavaScriptFromString:js];
-
- }
-
- }
- - (void)setPlaceholderText {
-
- //Call the setPlaceholder javascript method if a placeholder has been set
- if (self.placeholder != NULL && [self.placeholder length] != 0) {
-
- NSString *js = [NSString stringWithFormat:@"zss_editor.setPlaceholder(\"%@\");", self.placeholder];
- [self.editorView stringByEvaluatingJavaScriptFromString:js];
-
- }
-
- }
- - (void)setFooterHeight:(float)footerHeight {
-
- //Call the setFooterHeight javascript method
- NSString *js = [NSString stringWithFormat:@"zss_editor.setFooterHeight(\"%f\");", footerHeight];
- [self.editorView stringByEvaluatingJavaScriptFromString:js];
-
- }
- - (void)setContentHeight:(float)contentHeight {
-
- //Call the contentHeight javascript method
- NSString *js = [NSString stringWithFormat:@"zss_editor.contentHeight = %f;", contentHeight];
- [self.editorView stringByEvaluatingJavaScriptFromString:js];
-
- }
- #pragma mark - Editor Interaction
- - (void)focusTextEditor {
- self.editorView.keyboardDisplayRequiresUserAction = NO;
- NSString *js = [NSString stringWithFormat:@"zss_editor.focusEditor();"];
- [self.editorView stringByEvaluatingJavaScriptFromString:js];
- }
- - (void)blurTextEditor {
- NSString *js = [NSString stringWithFormat:@"zss_editor.blurEditor();"];
- [self.editorView stringByEvaluatingJavaScriptFromString:js];
- }
- - (void)setHTML:(NSString *)html {
-
- self.internalHTML = html;
-
- if (self.editorLoaded) {
- [self updateHTML];
- }
-
- }
- - (void)updateHTML {
-
- NSString *html = self.internalHTML;
- self.sourceView.text = html;
- NSString *cleanedHTML = [self removeQuotesFromHTML:self.sourceView.text];
- NSString *trigger = [NSString stringWithFormat:@"zss_editor.setHTML(\"%@\");", cleanedHTML];
- [self.editorView stringByEvaluatingJavaScriptFromString:trigger];
-
- }
- - (NSString *)getHTML {
-
- NSString *html = [self.editorView stringByEvaluatingJavaScriptFromString:@"zss_editor.getHTML();"];
- html = [self removeQuotesFromHTML:html];
- html = [self tidyHTML:html];
- return html;
-
- }
- - (void)insertHTML:(NSString *)html {
-
- NSString *cleanedHTML = [self removeQuotesFromHTML:html];
- NSString *trigger = [NSString stringWithFormat:@"zss_editor.insertHTML(\"%@\");", cleanedHTML];
- [self.editorView stringByEvaluatingJavaScriptFromString:trigger];
-
- }
- - (NSString *)getText {
-
- return [self.editorView stringByEvaluatingJavaScriptFromString:@"zss_editor.getText();"];
-
- }
- - (void)dismissKeyboard {
- [self.view endEditing:YES];
- }
- - (void)showHTMLSource:(ZSSBarButtonItem *)barButtonItem {
- if (self.sourceView.hidden) {
- self.sourceView.text = [self getHTML];
- self.sourceView.hidden = NO;
- barButtonItem.tintColor = [UIColor blackColor];
- self.editorView.hidden = YES;
- [self enableToolbarItems:NO];
- } else {
- [self setHTML:self.sourceView.text];
- barButtonItem.tintColor = [self barButtonItemDefaultColor];
- self.sourceView.hidden = YES;
- self.editorView.hidden = NO;
- [self enableToolbarItems:YES];
- }
- }
- - (void)removeFormat {
- NSString *trigger = @"zss_editor.removeFormating();";
- [self.editorView stringByEvaluatingJavaScriptFromString:trigger];
- }
- - (void)alignLeft {
- NSString *trigger = @"zss_editor.setJustifyLeft();";
- [self.editorView stringByEvaluatingJavaScriptFromString:trigger];
- }
- - (void)alignCenter {
- NSString *trigger = @"zss_editor.setJustifyCenter();";
- [self.editorView stringByEvaluatingJavaScriptFromString:trigger];
- }
- - (void)alignRight {
- NSString *trigger = @"zss_editor.setJustifyRight();";
- [self.editorView stringByEvaluatingJavaScriptFromString:trigger];
- }
- - (void)alignFull {
- NSString *trigger = @"zss_editor.setJustifyFull();";
- [self.editorView stringByEvaluatingJavaScriptFromString:trigger];
- }
- - (void)setBold {
- NSString *trigger = @"zss_editor.setBold();";
- [self.editorView stringByEvaluatingJavaScriptFromString:trigger];
- }
- - (void)setItalic {
- NSString *trigger = @"zss_editor.setItalic();";
- [self.editorView stringByEvaluatingJavaScriptFromString:trigger];
- }
- - (void)setSubscript {
- NSString *trigger = @"zss_editor.setSubscript();";
- [self.editorView stringByEvaluatingJavaScriptFromString:trigger];
- }
- - (void)setUnderline {
- NSString *trigger = @"zss_editor.setUnderline();";
- [self.editorView stringByEvaluatingJavaScriptFromString:trigger];
- }
- - (void)setSuperscript {
- NSString *trigger = @"zss_editor.setSuperscript();";
- [self.editorView stringByEvaluatingJavaScriptFromString:trigger];
- }
- - (void)setStrikethrough {
- NSString *trigger = @"zss_editor.setStrikeThrough();";
- [self.editorView stringByEvaluatingJavaScriptFromString:trigger];
- }
- - (void)setUnorderedList {
- NSString *trigger = @"zss_editor.setUnorderedList();";
- [self.editorView stringByEvaluatingJavaScriptFromString:trigger];
- }
- - (void)setOrderedList {
- NSString *trigger = @"zss_editor.setOrderedList();";
- [self.editorView stringByEvaluatingJavaScriptFromString:trigger];
- }
- - (void)setHR {
- NSString *trigger = @"zss_editor.setHorizontalRule();";
- [self.editorView stringByEvaluatingJavaScriptFromString:trigger];
- }
- - (void)setIndent {
- NSString *trigger = @"zss_editor.setIndent();";
- [self.editorView stringByEvaluatingJavaScriptFromString:trigger];
- }
- - (void)setOutdent {
- NSString *trigger = @"zss_editor.setOutdent();";
- [self.editorView stringByEvaluatingJavaScriptFromString:trigger];
- }
- - (void)heading1 {
- NSString *trigger = @"zss_editor.setHeading('h1');";
- [self.editorView stringByEvaluatingJavaScriptFromString:trigger];
- }
- - (void)heading2 {
- NSString *trigger = @"zss_editor.setHeading('h2');";
- [self.editorView stringByEvaluatingJavaScriptFromString:trigger];
- }
- - (void)heading3 {
- NSString *trigger = @"zss_editor.setHeading('h3');";
- [self.editorView stringByEvaluatingJavaScriptFromString:trigger];
- }
- - (void)heading4 {
- NSString *trigger = @"zss_editor.setHeading('h4');";
- [self.editorView stringByEvaluatingJavaScriptFromString:trigger];
- }
- - (void)heading5 {
- NSString *trigger = @"zss_editor.setHeading('h5');";
- [self.editorView stringByEvaluatingJavaScriptFromString:trigger];
- }
- - (void)heading6 {
- NSString *trigger = @"zss_editor.setHeading('h6');";
- [self.editorView stringByEvaluatingJavaScriptFromString:trigger];
- }
- - (void)paragraph {
- NSString *trigger = @"zss_editor.setParagraph();";
- [self.editorView stringByEvaluatingJavaScriptFromString:trigger];
- }
- - (void)showFontsPicker {
-
- // Save the selection location
- [self.editorView stringByEvaluatingJavaScriptFromString:@"zss_editor.prepareInsert();"];
-
- //Call picker
- ZSSFontsViewController *fontPicker = [ZSSFontsViewController cancelableFontPickerViewControllerWithFontFamily:ZSSFontFamilyDefault];
- fontPicker.delegate = self;
- [self.navigationController pushViewController:fontPicker animated:YES];
-
- }
- - (void)setSelectedFontFamily:(ZSSFontFamily)fontFamily {
-
- NSString *fontFamilyString;
-
- switch (fontFamily) {
- case ZSSFontFamilyDefault:
- fontFamilyString = @"Arial, Helvetica, sans-serif";
- break;
-
- case ZSSFontFamilyGeorgia:
- fontFamilyString = @"Georgia, serif";
- break;
-
- case ZSSFontFamilyPalatino:
- fontFamilyString = @"Palatino Linotype, Book Antiqua, Palatino, serif";
- break;
-
- case ZSSFontFamilyTimesNew:
- fontFamilyString = @"Times New Roman, Times, serif";
- break;
-
- case ZSSFontFamilyTrebuchet:
- fontFamilyString = @"Trebuchet MS, Helvetica, sans-serif";
- break;
-
- case ZSSFontFamilyVerdana:
- fontFamilyString = @"Verdana, Geneva, sans-serif";
- break;
-
- case ZSSFontFamilyCourierNew:
- fontFamilyString = @"Courier New, Courier, monospace";
- break;
-
- default:
- fontFamilyString = @"Arial, Helvetica, sans-serif";
- break;
- }
-
- NSString *trigger = [NSString stringWithFormat:@"zss_editor.setFontFamily(\"%@\");", fontFamilyString];
- [self.editorView stringByEvaluatingJavaScriptFromString:trigger];
-
- }
- - (void)textColor {
-
- // Save the selection location
- [self.editorView stringByEvaluatingJavaScriptFromString:@"zss_editor.prepareInsert();"];
-
- // Call the picker
- HRColorPickerViewController *colorPicker = [HRColorPickerViewController cancelableFullColorPickerViewControllerWithColor:[UIColor whiteColor]];
- colorPicker.delegate = self;
- colorPicker.tag = 1;
- colorPicker.title = NSLocalizedString(@"Text Color", nil);
- [self.navigationController pushViewController:colorPicker animated:YES];
-
- }
- - (void)bgColor {
-
- // Save the selection location
- [self.editorView stringByEvaluatingJavaScriptFromString:@"zss_editor.prepareInsert();"];
-
- // Call the picker
- HRColorPickerViewController *colorPicker = [HRColorPickerViewController cancelableFullColorPickerViewControllerWithColor:[UIColor whiteColor]];
- colorPicker.delegate = self;
- colorPicker.tag = 2;
- colorPicker.title = NSLocalizedString(@"BG Color", nil);
- [self.navigationController pushViewController:colorPicker animated:YES];
-
- }
- - (void)setSelectedColor:(UIColor*)color tag:(int)tag {
-
- NSString *hex = [NSString stringWithFormat:@"#%06x",HexColorFromUIColor(color)];
- NSString *trigger;
- if (tag == 1) {
- trigger = [NSString stringWithFormat:@"zss_editor.setTextColor(\"%@\");", hex];
- } else if (tag == 2) {
- trigger = [NSString stringWithFormat:@"zss_editor.setBackgroundColor(\"%@\");", hex];
- }
- [self.editorView stringByEvaluatingJavaScriptFromString:trigger];
-
- }
- - (void)undo:(ZSSBarButtonItem *)barButtonItem {
- [self.editorView stringByEvaluatingJavaScriptFromString:@"zss_editor.undo();"];
- }
- - (void)redo:(ZSSBarButtonItem *)barButtonItem {
- [self.editorView stringByEvaluatingJavaScriptFromString:@"zss_editor.redo();"];
- }
- - (void)insertLink {
-
- // Save the selection location
- [self.editorView stringByEvaluatingJavaScriptFromString:@"zss_editor.prepareInsert();"];
-
- // Show the dialog for inserting or editing a link
- [self showInsertLinkDialogWithLink:self.selectedLinkURL title:self.selectedLinkTitle];
-
- }
- - (void)showInsertLinkDialogWithLink:(NSString *)url title:(NSString *)title {
-
- // Insert Button Title
- NSString *insertButtonTitle = !self.selectedLinkURL ? NSLocalizedString(@"Insert", nil) : NSLocalizedString(@"Update", nil);
-
- // Picker Button
- UIButton *am = [UIButton buttonWithType:UIButtonTypeCustom];
- am.frame = CGRectMake(0, 0, 25, 25);
- [am setImage:[UIImage imageNamed:@"ZSSpicker.png"] forState:UIControlStateNormal];
- [am addTarget:self action:@selector(showInsertURLAlternatePicker) forControlEvents:UIControlEventTouchUpInside];
-
- if ([NSProcessInfo instancesRespondToSelector:@selector(isOperatingSystemAtLeastVersion:)]) {
-
- UIAlertController *alertController = [UIAlertController alertControllerWithTitle:NSLocalizedString(@"Insert Link", nil) message:nil preferredStyle:UIAlertControllerStyleAlert];
- [alertController addTextFieldWithConfigurationHandler:^(UITextField *textField) {
- textField.placeholder = NSLocalizedString(@"URL (required)", nil);
- if (url) {
- textField.text = url;
- }
- textField.rightView = am;
- textField.rightViewMode = UITextFieldViewModeAlways;
- textField.clearButtonMode = UITextFieldViewModeAlways;
- }];
- [alertController addTextFieldWithConfigurationHandler:^(UITextField *textField) {
- textField.placeholder = NSLocalizedString(@"Title", nil);
- textField.clearButtonMode = UITextFieldViewModeAlways;
- textField.secureTextEntry = NO;
- if (title) {
- textField.text = title;
- }
- }];
- [alertController addAction:[UIAlertAction actionWithTitle:NSLocalizedString(@"Cancel", nil) style:UIAlertActionStyleCancel handler:^(UIAlertAction *action) {
- [self focusTextEditor];
- }]];
- [alertController addAction:[UIAlertAction actionWithTitle:insertButtonTitle style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
-
- UITextField *linkURL = [alertController.textFields objectAtIndex:0];
- UITextField *title = [alertController.textFields objectAtIndex:1];
- if (!self.selectedLinkURL) {
- [self insertLink:linkURL.text title:title.text];
- //NSLog(@"insert link");
- } else {
- [self updateLink:linkURL.text title:title.text];
- }
- [self focusTextEditor];
- }]];
- [self presentViewController:alertController animated:YES completion:NULL];
-
- } else {
-
- self.alertView = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Insert Link", nil) message:nil delegate:self cancelButtonTitle:NSLocalizedString(@"Cancel", nil) otherButtonTitles:insertButtonTitle, nil];
- self.alertView.alertViewStyle = UIAlertViewStyleLoginAndPasswordInput;
- self.alertView.tag = 2;
- UITextField *linkURL = [self.alertView textFieldAtIndex:0];
- linkURL.placeholder = NSLocalizedString(@"URL (required)", nil);
- if (url) {
- linkURL.text = url;
- }
-
- linkURL.rightView = am;
- linkURL.rightViewMode = UITextFieldViewModeAlways;
-
- UITextField *alt = [self.alertView textFieldAtIndex:1];
- alt.secureTextEntry = NO;
- alt.placeholder = NSLocalizedString(@"Title", nil);
- if (title) {
- alt.text = title;
- }
-
- [self.alertView show];
- }
-
- }
- - (void)insertLink:(NSString *)url title:(NSString *)title {
-
- NSString *trigger = [NSString stringWithFormat:@"zss_editor.insertLink(\"%@\", \"%@\");", url, title];
- [self.editorView stringByEvaluatingJavaScriptFromString:trigger];
-
- }
- - (void)updateLink:(NSString *)url title:(NSString *)title {
- NSString *trigger = [NSString stringWithFormat:@"zss_editor.updateLink(\"%@\", \"%@\");", url, title];
- [self.editorView stringByEvaluatingJavaScriptFromString:trigger];
- }
- - (void)dismissAlertView {
- [self.alertView dismissWithClickedButtonIndex:self.alertView.cancelButtonIndex animated:YES];
- }
- - (void)addCustomToolbarItemWithButton:(UIButton *)button {
-
- if(self.customBarButtonItems == nil)
- {
- self.customBarButtonItems = [NSMutableArray array];
- }
-
- button.titleLabel.font = [UIFont fontWithName:@"HelveticaNeue-UltraLight" size:28.5f];
- [button setTitleColor:[self barButtonItemDefaultColor] forState:UIControlStateNormal];
- [button setTitleColor:[self barButtonItemSelectedDefaultColor] forState:UIControlStateHighlighted];
-
- ZSSBarButtonItem *barButtonItem = [[ZSSBarButtonItem alloc] initWithCustomView:button];
-
- [self.customBarButtonItems addObject:barButtonItem];
-
- [self buildToolbar];
- }
- - (void)addCustomToolbarItem:(ZSSBarButtonItem *)item {
-
- if(self.customZSSBarButtonItems == nil)
- {
- self.customZSSBarButtonItems = [NSMutableArray array];
- }
- [self.customZSSBarButtonItems addObject:item];
-
- [self buildToolbar];
- }
- - (void)removeLink {
- [self.editorView stringByEvaluatingJavaScriptFromString:@"zss_editor.unlink();"];
- }
- - (void)quickLink {
- [self.editorView stringByEvaluatingJavaScriptFromString:@"zss_editor.quickLink();"];
- }
- - (void)insertImage {
-
- // Save the selection location
- [self.editorView stringByEvaluatingJavaScriptFromString:@"zss_editor.prepareInsert();"];
-
- [self showInsertImageDialogWithLink:self.selectedImageURL alt:self.selectedImageAlt];
-
- }
- - (void)insertImageFromDevice {
-
- // Save the selection location
- [self.editorView stringByEvaluatingJavaScriptFromString:@"zss_editor.prepareInsert();"];
-
- [self showInsertImageDialogFromDeviceWithScale:self.selectedImageScale alt:self.selectedImageAlt];
-
- }
- - (void)showInsertImageDialogWithLink:(NSString *)url alt:(NSString *)alt {
-
- // Insert Button Title
- NSString *insertButtonTitle = !self.selectedImageURL ? NSLocalizedString(@"Insert", nil) : NSLocalizedString(@"Update", nil);
-
- // Picker Button
- UIButton *am = [UIButton buttonWithType:UIButtonTypeCustom];
- am.frame = CGRectMake(0, 0, 25, 25);
- [am setImage:[UIImage imageNamed:@"ZSSpicker.png"] forState:UIControlStateNormal];
- [am addTarget:self action:@selector(showInsertImageAlternatePicker) forControlEvents:UIControlEventTouchUpInside];
-
- if ([NSProcessInfo instancesRespondToSelector:@selector(isOperatingSystemAtLeastVersion:)]) {
-
- UIAlertController *alertController = [UIAlertController alertControllerWithTitle:NSLocalizedString(@"Insert Image", nil) message:nil preferredStyle:UIAlertControllerStyleAlert];
- [alertController addTextFieldWithConfigurationHandler:^(UITextField *textField) {
- textField.placeholder = NSLocalizedString(@"URL (required)", nil);
- if (url) {
- textField.text = url;
- }
- textField.rightView = am;
- textField.rightViewMode = UITextFieldViewModeAlways;
- textField.clearButtonMode = UITextFieldViewModeAlways;
- }];
- [alertController addTextFieldWithConfigurationHandler:^(UITextField *textField) {
- textField.placeholder = NSLocalizedString(@"Alt", nil);
- textField.clearButtonMode = UITextFieldViewModeAlways;
- textField.secureTextEntry = NO;
- if (alt) {
- textField.text = alt;
- }
- }];
- [alertController addAction:[UIAlertAction actionWithTitle:NSLocalizedString(@"Cancel", nil) style:UIAlertActionStyleCancel handler:^(UIAlertAction *action) {
- [self focusTextEditor];
- }]];
- [alertController addAction:[UIAlertAction actionWithTitle:insertButtonTitle style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
-
- UITextField *imageURL = [alertController.textFields objectAtIndex:0];
- UITextField *alt = [alertController.textFields objectAtIndex:1];
- if (!self.selectedImageURL) {
- [self insertImage:imageURL.text alt:alt.text];
- } else {
- [self updateImage:imageURL.text alt:alt.text];
- }
- [self focusTextEditor];
- }]];
- [self presentViewController:alertController animated:YES completion:NULL];
-
- } else {
-
- self.alertView = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Insert Image", nil) message:nil delegate:self cancelButtonTitle:NSLocalizedString(@"Cancel", nil) otherButtonTitles:insertButtonTitle, nil];
- self.alertView.alertViewStyle = UIAlertViewStyleLoginAndPasswordInput;
- self.alertView.tag = 1;
- UITextField *imageURL = [self.alertView textFieldAtIndex:0];
- imageURL.placeholder = NSLocalizedString(@"URL (required)", nil);
- if (url) {
- imageURL.text = url;
- }
-
- imageURL.rightView = am;
- imageURL.rightViewMode = UITextFieldViewModeAlways;
- imageURL.clearButtonMode = UITextFieldViewModeAlways;
-
- UITextField *alt1 = [self.alertView textFieldAtIndex:1];
- alt1.secureTextEntry = NO;
- alt1.placeholder = NSLocalizedString(@"Alt", nil);
- alt1.clearButtonMode = UITextFieldViewModeAlways;
- if (alt) {
- alt1.text = alt;
- }
-
- [self.alertView show];
- }
-
- }
- - (void)showInsertImageDialogFromDeviceWithScale:(CGFloat)scale alt:(NSString *)alt {
-
- // Insert button title
- NSString *insertButtonTitle = !self.selectedImageURL ? NSLocalizedString(@"Pick Image", nil) : NSLocalizedString(@"Pick New Image", nil);
-
- //If the OS version supports the new UIAlertController go for it. Otherwise use the old UIAlertView
- if ([NSProcessInfo instancesRespondToSelector:@selector(isOperatingSystemAtLeastVersion:)]) {
-
- UIAlertController *alertController = [UIAlertController alertControllerWithTitle:NSLocalizedString(@"Insert Image From Device", nil) message:nil preferredStyle:UIAlertControllerStyleAlert];
-
- //Add alt text field
- [alertController addTextFieldWithConfigurationHandler:^(UITextField *textField) {
- textField.placeholder = NSLocalizedString(@"Alt", nil);
- textField.clearButtonMode = UITextFieldViewModeAlways;
- textField.secureTextEntry = NO;
- if (alt) {
- textField.text = alt;
- }
- }];
-
- //Add scale text field
- [alertController addTextFieldWithConfigurationHandler:^(UITextField *textField) {
- textField.clearButtonMode = UITextFieldViewModeAlways;
- textField.secureTextEntry = NO;
- textField.placeholder = NSLocalizedString(@"Image scale, 0.3 by default", nil);
- textField.keyboardType = UIKeyboardTypeDecimalPad;
- }];
-
- //Cancel action
- [alertController addAction:[UIAlertAction actionWithTitle:NSLocalizedString(@"Cancel", nil) style:UIAlertActionStyleCancel handler:^(UIAlertAction *action) {
- [self focusTextEditor];
- }]];
-
- //Insert action
- [alertController addAction:[UIAlertAction actionWithTitle:insertButtonTitle style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
- UITextField *textFieldAlt = [alertController.textFields objectAtIndex:0];
- UITextField *textFieldScale = [alertController.textFields objectAtIndex:1];
- self.selectedImageScale = [textFieldScale.text floatValue]?:kDefaultScale;
- self.selectedImageAlt = textFieldAlt.text?:@"";
-
- [self presentViewController:self.imagePicker animated:YES completion:nil];
- }]];
-
- [self presentViewController:alertController animated:YES completion:NULL];
-
- } else {
-
- self.alertView = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Insert Image", nil) message:nil delegate:self cancelButtonTitle:NSLocalizedString(@"Cancel", nil) otherButtonTitles:insertButtonTitle, nil];
- self.alertView.alertViewStyle = UIAlertViewStyleLoginAndPasswordInput;
- self.alertView.tag = 3;
-
- UITextField *textFieldAlt = [self.alertView textFieldAtIndex:0];
- textFieldAlt.secureTextEntry = NO;
- textFieldAlt.placeholder = NSLocalizedString(@"Alt", nil);
- textFieldAlt.clearButtonMode = UITextFieldViewModeAlways;
- if (alt) {
- textFieldAlt.text = alt;
- }
-
- UITextField *textFieldScale = [self.alertView textFieldAtIndex:1];
- textFieldScale.placeholder = NSLocalizedString(@"Image scale, 0.3 by default", nil);
- textFieldScale.keyboardType = UIKeyboardTypeDecimalPad;
-
- [self.alertView show];
- }
-
- }
- - (void)insertImage:(NSString *)url alt:(NSString *)alt {
- NSString *trigger = [NSString stringWithFormat:@"zss_editor.insertImage(\"%@\", \"%@\");", url, alt];
- [self.editorView stringByEvaluatingJavaScriptFromString:trigger];
- }
- - (void)updateImage:(NSString *)url alt:(NSString *)alt {
- NSString *trigger = [NSString stringWithFormat:@"zss_editor.updateImage(\"%@\", \"%@\");", url, alt];
- [self.editorView stringByEvaluatingJavaScriptFromString:trigger];
- }
- - (void)insertImageBase64String:(NSString *)imageBase64String alt:(NSString *)alt {
- NSString *trigger = [NSString stringWithFormat:@"zss_editor.insertImageBase64String(\"%@\", \"%@\");", imageBase64String, alt];
- [self.editorView stringByEvaluatingJavaScriptFromString:trigger];
- }
- - (void)updateImageBase64String:(NSString *)imageBase64String alt:(NSString *)alt {
- NSString *trigger = [NSString stringWithFormat:@"zss_editor.updateImageBase64String(\"%@\", \"%@\");", imageBase64String, alt];
- [self.editorView stringByEvaluatingJavaScriptFromString:trigger];
- }
- - (void)updateToolBarWithButtonName:(NSString *)name {
-
- // Items that are enabled
- NSArray *itemNames = [name componentsSeparatedByString:@","];
-
- // Special case for link
- NSMutableArray *itemsModified = [[NSMutableArray alloc] init];
- for (NSString *linkItem in itemNames) {
- NSString *updatedItem = linkItem;
- if ([linkItem hasPrefix:@"link:"]) {
- updatedItem = @"link";
- self.selectedLinkURL = [linkItem stringByReplacingOccurrencesOfString:@"link:" withString:@""];
- } else if ([linkItem hasPrefix:@"link-title:"]) {
- self.selectedLinkTitle = [self stringByDecodingURLFormat:[linkItem stringByReplacingOccurrencesOfString:@"link-title:" withString:@""]];
- } else if ([linkItem hasPrefix:@"image:"]) {
- updatedItem = @"image";
- self.selectedImageURL = [linkItem stringByReplacingOccurrencesOfString:@"image:" withString:@""];
- } else if ([linkItem hasPrefix:@"image-alt:"]) {
- self.selectedImageAlt = [self stringByDecodingURLFormat:[linkItem stringByReplacingOccurrencesOfString:@"image-alt:" withString:@""]];
- } else {
- self.selectedImageURL = nil;
- self.selectedImageAlt = nil;
- self.selectedLinkURL = nil;
- self.selectedLinkTitle = nil;
- }
- [itemsModified addObject:updatedItem];
- }
- itemNames = [NSArray arrayWithArray:itemsModified];
-
- self.editorItemsEnabled = itemNames;
-
- // Highlight items
- NSArray *items = self.toolbar.items;
- for (ZSSBarButtonItem *item in items) {
- if ([itemNames containsObject:item.label]) {
- item.tintColor = [self barButtonItemSelectedDefaultColor];
- } else {
- item.tintColor = [self barButtonItemDefaultColor];
- }
- }
-
- }
- #pragma mark - UITextView Delegate
- - (void)textViewDidChange:(UITextView *)textView {
- CGRect line = [textView caretRectForPosition:textView.selectedTextRange.start];
- CGFloat overflow = line.origin.y + line.size.height - ( textView.contentOffset.y + textView.bounds.size.height - textView.contentInset.bottom - textView.contentInset.top );
- if ( overflow > 0 ) {
- // We are at the bottom of the visible text and introduced a line feed, scroll down (iOS 7 does not do it)
- // Scroll caret to visible area
- CGPoint offset = textView.contentOffset;
- offset.y += overflow + 7; // leave 7 pixels margin
- // Cannot animate with setContentOffset:animated: or caret will not appear
- [UIView animateWithDuration:.2 animations:^{
- [textView setContentOffset:offset];
- }];
- }
-
- }
- #pragma mark - UIWebView Delegate
- - (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
-
-
- NSString *urlString = [[request URL] absoluteString];
- //NSLog(@"web request");
- //NSLog(@"%@", urlString);
- if (navigationType == UIWebViewNavigationTypeLinkClicked) {
- return NO;
- } else if ([urlString rangeOfString:@"callback://0/"].location != NSNotFound) {
-
- // We recieved the callback
- NSString *className = [urlString stringByReplacingOccurrencesOfString:@"callback://0/" withString:@""];
- [self updateToolBarWithButtonName:className];
-
- } else if ([urlString rangeOfString:@"debug://"].location != NSNotFound) {
-
- NSLog(@"Debug Found");
-
- // We recieved the callback
- NSString *debug = [urlString stringByReplacingOccurrencesOfString:@"debug://" withString:@""];
- debug = [debug stringByReplacingPercentEscapesUsingEncoding:NSStringEncodingConversionAllowLossy];
- NSLog(@"%@", debug);
-
- } else if ([urlString rangeOfString:@"scroll://"].location != NSNotFound) {
-
- NSInteger position = [[urlString stringByReplacingOccurrencesOfString:@"scroll://" withString:@""] integerValue];
- [self editorDidScrollWithPosition:position];
-
- }
-
- return YES;
-
- }
- - (void)webViewDidFinishLoad:(UIWebView *)webView {
- self.editorLoaded = YES;
- if (!self.internalHTML) {
- self.internalHTML = @"";
- }
- [self updateHTML];
- if(self.placeholder) {
- [self setPlaceholderText];
- }
-
- if (self.customCSS) {
- [self updateCSS];
- }
- if (self.shouldShowKeyboard) {
- dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
- [self focusTextEditor];
- });
- }
-
- /*
-
- Callback for when text is changed, solution posted by richardortiz84 https://github.com/nnhubbard/ZSSRichTextEditor/issues/5
-
- */
- JSContext *ctx = [webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
- ctx[@"contentUpdateCallback"] = ^(JSValue *msg) {
-
- if (_receiveEditorDidChangeEvents) {
-
- [self editorDidChangeWithText:[self getText] andHTML:[self getHTML]];
-
- }
-
- [self checkForMentionOrHashtagInText:[self getText]];
-
- };
- [ctx evaluateScript:@"document.getElementById('zss_editor_content').addEventListener('input', contentUpdateCallback, false);"];
-
- }
- #pragma mark - Mention & Hashtag Support Section
- - (void)checkForMentionOrHashtagInText:(NSString *)text {
-
- if ([text containsString:@" "] && [text length] > 0) {
-
- NSString *lastWord = nil;
- NSString *matchedWord = nil;
- BOOL ContainsHashtag = NO;
- BOOL ContainsMention = NO;
-
- NSRange range = [text rangeOfString:@" " options:NSBackwardsSearch];
- lastWord = [text substringFromIndex:range.location];
-
- if (lastWord != nil) {
-
- //Check if last word typed starts with a #
- NSRegularExpression *hashtagRegex = [NSRegularExpression regularExpressionWithPattern:@"#(\\w+)" options:0 error:nil];
- NSArray *hashtagMatches = [hashtagRegex matchesInString:lastWord options:0 range:NSMakeRange(0, lastWord.length)];
-
- for (NSTextCheckingResult *match in hashtagMatches) {
-
- NSRange wordRange = [match rangeAtIndex:1];
- NSString *word = [lastWord substringWithRange:wordRange];
- matchedWord = word;
- ContainsHashtag = YES;
-
- }
-
- if (!ContainsHashtag) {
-
- //Check if last word typed starts with a @
- NSRegularExpression *mentionRegex = [NSRegularExpression regularExpressionWithPattern:@"@(\\w+)" options:0 error:nil];
- NSArray *mentionMatches = [mentionRegex matchesInString:lastWord options:0 range:NSMakeRange(0, lastWord.length)];
-
- for (NSTextCheckingResult *match in mentionMatches) {
-
- NSRange wordRange = [match rangeAtIndex:1];
- NSString *word = [lastWord substringWithRange:wordRange];
- matchedWord = word;
- ContainsMention = YES;
-
- }
-
- }
-
- }
-
- if (ContainsHashtag) {
-
- [self hashtagRecognizedWithWord:matchedWord];
-
- }
-
- if (ContainsMention) {
-
- [self mentionRecognizedWithWord:matchedWord];
-
- }
-
- }
-
- }
- #pragma mark - Callbacks
- //Blank implementation
- - (void)editorDidScrollWithPosition:(NSInteger)position {}
- //Blank implementation
- - (void)editorDidChangeWithText:(NSString *)text andHTML:(NSString *)html {}
- //Blank implementation
- - (void)hashtagRecognizedWithWord:(NSString *)word {}
- //Blank implementation
- - (void)mentionRecognizedWithWord:(NSString *)word {}
- #pragma mark - AlertView
- - (BOOL)alertViewShouldEnableFirstOtherButton:(UIAlertView *)alertView {
-
- if (alertView.tag == 1) {
- UITextField *textField = [alertView textFieldAtIndex:0];
- UITextField *textField2 = [alertView textFieldAtIndex:1];
- if ([textField.text length] == 0 || [textField2.text length] == 0) {
- return NO;
- }
- } else if (alertView.tag == 2) {
- UITextField *textField = [alertView textFieldAtIndex:0];
- if ([textField.text length] == 0) {
- return NO;
- }
- }
-
- return YES;
- }
- - (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
- if (alertView.tag == 1) {
- if (buttonIndex == 1) {
- UITextField *imageURL = [alertView textFieldAtIndex:0];
- UITextField *alt = [alertView textFieldAtIndex:1];
- if (!self.selectedImageURL) {
- [self insertImage:imageURL.text alt:alt.text];
- } else {
- [self updateImage:imageURL.text alt:alt.text];
- }
- }
- } else if (alertView.tag == 2) {
- if (buttonIndex == 1) {
- UITextField *linkURL = [alertView textFieldAtIndex:0];
- UITextField *title = [alertView textFieldAtIndex:1];
- if (!self.selectedLinkURL) {
- [self insertLink:linkURL.text title:title.text];
- } else {
- [self updateLink:linkURL.text title:title.text];
- }
- }
- } else if (alertView.tag == 3) {
- if (buttonIndex == 1) {
- UITextField *textFieldAlt = [alertView textFieldAtIndex:0];
- UITextField *textFieldScale = [alertView textFieldAtIndex:1];
-
- self.selectedImageScale = [textFieldScale.text floatValue]?:kDefaultScale;
- self.selectedImageAlt = textFieldAlt.text?:@"";
-
- [self presentViewController:self.imagePicker animated:YES completion:nil];
- }
- }
- }
- #pragma mark - Asset Picker
- - (void)showInsertURLAlternatePicker {
- // Blank method. User should implement this in their subclass
- }
- - (void)showInsertImageAlternatePicker {
- // Blank method. User should implement this in their subclass
- }
- #pragma mark - Image Picker Delegate
- - (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker{
- //Dismiss the Image Picker
- [self.navigationController dismissViewControllerAnimated:YES completion:nil];
- }
- - (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary<NSString *, id> *)info{
- UIImage *selectedImage = info[UIImagePickerControllerEditedImage]?:info[UIImagePickerControllerOriginalImage];
-
- //Scale the image
- CGSize targetSize = CGSizeMake(selectedImage.size.width * self.selectedImageScale, selectedImage.size.height * self.selectedImageScale);
- UIGraphicsBeginImageContext(targetSize);
- [selectedImage drawInRect:CGRectMake(0,0,targetSize.width,targetSize.height)];
- UIImage* scaledImage = UIGraphicsGetImageFromCurrentImageContext();
- UIGraphicsEndImageContext();
- //Compress the image, as it is going to be encoded rather than linked
- NSData *scaledImageData = UIImageJPEGRepresentation(scaledImage, kJPEGCompression);
-
- //Encode the image data as a base64 string
- NSString *imageBase64String = [scaledImageData base64EncodedStringWithOptions:0];
-
- //Decide if we have to insert or update
- if (!self.imageBase64String) {
- [self insertImageBase64String:imageBase64String alt:self.selectedImageAlt];
- } else {
- [self updateImageBase64String:imageBase64String alt:self.selectedImageAlt];
- }
-
- self.imageBase64String = imageBase64String;
- //Dismiss the Image Picker
- [self.navigationController dismissViewControllerAnimated:YES completion:nil];
- }
- #pragma mark - Keyboard status
- - (void)keyboardWillShowOrHide:(NSNotification *)notification {
-
- // Orientation
- UIInterfaceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation;
-
- // User Info
- NSDictionary *info = notification.userInfo;
- CGFloat duration = [[info objectForKey:UIKeyboardAnimationDurationUserInfoKey] floatValue];
- int curve = [[info objectForKey:UIKeyboardAnimationCurveUserInfoKey] intValue];
- CGRect keyboardEnd = [[info objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue];
-
- // Toolbar Sizes
- CGFloat sizeOfToolbar = self.toolbarHolder.frame.size.height;
-
- // Keyboard Size
- //Checks if IOS8, gets correct keyboard height
- CGFloat keyboardHeight = UIInterfaceOrientationIsLandscape(orientation) ? ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.000000) ? keyboardEnd.size.height : keyboardEnd.size.width : keyboardEnd.size.height;
-
- // Correct Curve
- UIViewAnimationOptions animationOptions = curve << 16;
-
- const int extraHeight = 10;
-
- if ([notification.name isEqualToString:UIKeyboardWillShowNotification]) {
-
- [UIView animateWithDuration:duration delay:0 options:animationOptions animations:^{
-
- // Toolbar
- CGRect frame = self.toolbarHolder.frame;
- frame.origin.y = self.view.frame.size.height - (keyboardHeight + sizeOfToolbar);
- self.toolbarHolder.frame = frame;
-
- // Editor View
- CGRect editorFrame = self.editorView.frame;
- editorFrame.size.height = (self.view.frame.size.height - keyboardHeight) - sizeOfToolbar - extraHeight;
- self.editorView.frame = editorFrame;
- self.editorViewFrame = self.editorView.frame;
- self.editorView.scrollView.contentInset = UIEdgeInsetsZero;
- self.editorView.scrollView.scrollIndicatorInsets = UIEdgeInsetsZero;
-
- // Source View
- CGRect sourceFrame = self.sourceView.frame;
- sourceFrame.size.height = (self.view.frame.size.height - keyboardHeight) - sizeOfToolbar - extraHeight;
- self.sourceView.frame = sourceFrame;
-
- // Provide editor with keyboard height and editor view height
- [self setFooterHeight:(keyboardHeight - 8)];
- [self setContentHeight: self.editorViewFrame.size.height];
-
- } completion:nil];
-
- } else {
-
- [UIView animateWithDuration:duration delay:0 options:animationOptions animations:^{
-
- CGRect frame = self.toolbarHolder.frame;
-
- if (_alwaysShowToolbar) {
- frame.origin.y = self.view.frame.size.height - sizeOfToolbar;
- } else {
- frame.origin.y = self.view.frame.size.height + keyboardHeight;
- }
-
- self.toolbarHolder.frame = frame;
-
- // Editor View
- CGRect editorFrame = self.editorView.frame;
-
- if (_alwaysShowToolbar) {
- editorFrame.size.height = ((self.view.frame.size.height - sizeOfToolbar) - extraHeight);
- } else {
- editorFrame.size.height = self.view.frame.size.height;
- }
-
- self.editorView.frame = editorFrame;
- self.editorViewFrame = self.editorView.frame;
- self.editorView.scrollView.contentInset = UIEdgeInsetsZero;
- self.editorView.scrollView.scrollIndicatorInsets = UIEdgeInsetsZero;
-
- // Source View
- CGRect sourceFrame = self.sourceView.frame;
-
- if (_alwaysShowToolbar) {
- sourceFrame.size.height = ((self.view.frame.size.height - sizeOfToolbar) - extraHeight);
- } else {
- sourceFrame.size.height = self.view.frame.size.height;
- }
-
- self.sourceView.frame = sourceFrame;
-
- } completion:nil];
-
- }
-
- }
- #pragma mark - Utilities
- - (NSString *)removeQuotesFromHTML:(NSString *)html {
- html = [html stringByReplacingOccurrencesOfString:@"\"" withString:@"\\\""];
- html = [html stringByReplacingOccurrencesOfString:@"“" withString:@"""];
- html = [html stringByReplacingOccurrencesOfString:@"”" withString:@"""];
- html = [html stringByReplacingOccurrencesOfString:@"\r" withString:@"\\r"];
- html = [html stringByReplacingOccurrencesOfString:@"\n" withString:@"\\n"];
- return html;
- }
- - (NSString *)tidyHTML:(NSString *)html {
- html = [html stringByReplacingOccurrencesOfString:@"<br>" withString:@"<br />"];
- html = [html stringByReplacingOccurrencesOfString:@"<hr>" withString:@"<hr />"];
- if (self.formatHTML) {
- html = [self.editorView stringByEvaluatingJavaScriptFromString:[NSString stringWithFormat:@"style_html(\"%@\");", html]];
- }
- return html;
- }
- - (UIColor *)barButtonItemDefaultColor {
-
- if (self.toolbarItemTintColor) {
- return self.toolbarItemTintColor;
- }
-
- return [UIColor colorWithRed:0.0f/255.0f green:122.0f/255.0f blue:255.0f/255.0f alpha:1.0f];
- }
- - (UIColor *)barButtonItemSelectedDefaultColor {
-
- if (self.toolbarItemSelectedTintColor) {
- return self.toolbarItemSelectedTintColor;
- }
-
- return [UIColor blackColor];
- }
- - (BOOL)isIpad {
- return (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad);
- }
- - (NSString *)stringByDecodingURLFormat:(NSString *)string {
- NSString *result = [string stringByReplacingOccurrencesOfString:@"+" withString:@" "];
- result = [result stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
- return result;
- }
- - (void)enableToolbarItems:(BOOL)enable {
- NSArray *items = self.toolbar.items;
- for (ZSSBarButtonItem *item in items) {
- if (![item.label isEqualToString:@"source"]) {
- item.enabled = enable;
- }
- }
- }
- #pragma mark - Memory Warning Section
- - (void)didReceiveMemoryWarning {
- [super didReceiveMemoryWarning];
- }
- @end
|