├── .github ├── CONTRIBUTING.md ├── ISSUE_TEMPLATE.md └── PULL_REQUEST_TEMPLATE.md ├── .gitignore ├── .gitmodules ├── Classes ├── AppDelegate.h ├── AppDelegate.m ├── BaseViewController.h ├── BaseViewController.m ├── Bookmark.h ├── Bookmark.m ├── BookmarkDatabase.h ├── BookmarkDatabase.m ├── BookmarkListController.h ├── BookmarkListController.m ├── ContainerController.h ├── ContainerController.m ├── ContainerList.h ├── ContainerList.m ├── ContainerListController.h ├── ContainerListController.m ├── EPubSettings.h ├── EPubSettings.m ├── EPubSettingsController.h ├── EPubSettingsController.m ├── EPubViewController.h ├── EPubViewController.m ├── LocStr.h ├── LocStr.m ├── NavigationElementController.h ├── NavigationElementController.m ├── NavigationElementItem.h ├── NavigationElementItem.m ├── PackageMetadataController.h ├── PackageMetadataController.m ├── Settings.h ├── Settings.m ├── SpineItemListController.h ├── SpineItemListController.m └── main.m ├── Other └── Icon-512@2x.png ├── README.md ├── Resources ├── Default-568h@2x.png ├── Default-Landscape.png ├── Default-Landscape@2x.png ├── Default-Portrait.png ├── Default-Portrait@2x.png ├── Default.png ├── Default@2x.png ├── Icon-29.png ├── Icon-29@2x.png ├── Icon-40.png ├── Icon-40@2x.png ├── Icon-50.png ├── Icon-50@2x.png ├── Icon-57.png ├── Icon-57@2x.png ├── Icon-60@2x.png ├── Icon-72.png ├── Icon-72@2x.png ├── Icon-76.png ├── Icon-76@2x.png ├── annotations.css ├── childrens-literature-20130206.epub ├── en.lproj │ └── Localizable.strings ├── epub30-test-0120-20131022.epub ├── epub30-test-0220-20131022.epub ├── epubReadingSystem.epub ├── epubReadingSystem.js ├── epubReadingSystem.sh ├── host_app_feedback.js ├── mathjax │ └── MathJax.js ├── moby-dick-20120118.epub ├── page-blanche-20130322.epub ├── reader.css ├── reader.html ├── reader_RequireJS-multiple-bundles.html ├── reader_RequireJS-no-optimize.html ├── reader_RequireJS-single-bundle.html └── wasteland-20120118.epub ├── SDKLauncher-iOS-Info.plist ├── SDKLauncher-iOS-Prefix.pch ├── SDKLauncher-iOS.xcodeproj └── project.pbxproj ├── build.xml └── license.txt /.github/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # How to contribute to Readium 2 | 3 | Please visit this link for more information: 4 | http://readium.github.io/contributing.html 5 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | *General Instructions* 2 | 3 | - *Please use a short, but meaningful title.* 4 | - *Delete everything in italics before submitting issue* 5 | - *Make sure to fill in as much information as possible* 6 | 7 | #### This issue is a Bug|Feature Request|Enhancement|Question|Task|Other 8 | *(choose ONE from the above list and delete the others)* 9 | 10 | #### Related issue(s) and/or pull request(s) 11 | *Example: See also #NUMBER* 12 | 13 | #### Expected Behaviour 14 | *What you expected Readium to do...* 15 | 16 | #### Observed behaviour 17 | *Instead, Readium does...* 18 | 19 | #### Steps to reproduce 20 | 1. First, do this 21 | 2. Then do this 22 | 3. etc. 23 | 24 | #### Test file(s) 25 | *If relevant, please indicate public EPUB URL(s), or whether you can share ebook(s) privately. It is often next to impossible to reproduce bugs without the original file.* 26 | 27 | ### Product 28 | *Choose one of the following (and delete the others)* 29 | 30 | * Readium Chrome extension 31 | * latest official version available from the Chrome Web Store 32 | * Version of the Chrome browser 33 | * OS and version 34 | * Readium cloud reader app 35 | * latest development build uploaded at https://readium.firebaseapp.com OR a custom integration (list public deployment URL, if any) 36 | * Browser and version 37 | * OS and version 38 | * Native application (Readium SDK C++) 39 | * official "launcher" sample OR propietary app 40 | * OS and version 41 | * Hybrid app (ReadiumJS) 42 | * Electron OR Apache Cordova OR ? 43 | * OS and version 44 | * Other? 45 | 46 | #### Additional information 47 | *Please list any additional information that might help us* 48 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | *General Instructions* 2 | 3 | - *Please use a short, but meaningful title.* 4 | - *Delete everything in italics before submitting the pull request* 5 | - *Make sure to fill in as much information as possible* 6 | 7 | #### This pull request is a Work In Progress|Finalized|Other 8 | *(choose ONE from the above list and delete the others)* 9 | 10 | #### Related issue(s) and/or pull request(s) 11 | *Example: See also #NUMBER* 12 | 13 | #### Test cases, sample files 14 | 15 | *(if relevant, please indicate public EPUB URL(s), or whether you can share ebook(s) privately)* 16 | 17 | 18 | ### Additional information 19 | *Please provide any and all information that might help us* 20 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | project.xcworkspace 3 | xcuserdata 4 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "readium-sdk"] 2 | path = readium-sdk 3 | url = https://github.com/readium/readium-sdk.git 4 | [submodule "Resources/readium-shared-js"] 5 | path = Resources/readium-shared-js 6 | url = https://github.com/readium/readium-shared-js.git 7 | -------------------------------------------------------------------------------- /Classes/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // SDKLauncher-iOS 4 | // 5 | // Created by Shane Meyer on 2/1/13. 6 | // Copyright (c) 2014 Readium Foundation and/or its licensees. All rights reserved. 7 | // 8 | // Redistribution and use in source and binary forms, with or without modification, 9 | // are permitted provided that the following conditions are met: 10 | // 1. Redistributions of source code must retain the above copyright notice, this 11 | // list of conditions and the following disclaimer. 12 | // 2. Redistributions in binary form must reproduce the above copyright notice, 13 | // this list of conditions and the following disclaimer in the documentation and/or 14 | // other materials provided with the distribution. 15 | // 3. Neither the name of the organization nor the names of its contributors may be 16 | // used to endorse or promote products derived from this software without specific 17 | // prior written permission. 18 | // 19 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 20 | // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 | // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 22 | // IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 23 | // INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 24 | // BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 26 | // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 27 | // OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 28 | // OF THE POSSIBILITY OF SUCH DAMAGE. 29 | 30 | #import 31 | 32 | @interface AppDelegate : UIResponder 33 | 34 | @property (nonatomic, strong) UIWindow *window; 35 | 36 | @end 37 | -------------------------------------------------------------------------------- /Classes/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // SDKLauncher-iOS 4 | // 5 | // Created by Shane Meyer on 2/1/13. 6 | // Copyright (c) 2014 Readium Foundation and/or its licensees. All rights reserved. 7 | // 8 | // Redistribution and use in source and binary forms, with or without modification, 9 | // are permitted provided that the following conditions are met: 10 | // 1. Redistributions of source code must retain the above copyright notice, this 11 | // list of conditions and the following disclaimer. 12 | // 2. Redistributions in binary form must reproduce the above copyright notice, 13 | // this list of conditions and the following disclaimer in the documentation and/or 14 | // other materials provided with the distribution. 15 | // 3. Neither the name of the organization nor the names of its contributors may be 16 | // used to endorse or promote products derived from this software without specific 17 | // prior written permission. 18 | // 19 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 20 | // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 | // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 22 | // IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 23 | // INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 24 | // BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 26 | // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 27 | // OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 28 | // OF THE POSSIBILITY OF SUCH DAMAGE. 29 | 30 | #import "AppDelegate.h" 31 | #import 32 | #import "ContainerListController.h" 33 | 34 | 35 | @interface AppDelegate() 36 | 37 | - (void)configureAppearance; 38 | 39 | @end 40 | 41 | 42 | @implementation AppDelegate 43 | 44 | 45 | - (BOOL) 46 | application:(UIApplication *)application 47 | didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 48 | { 49 | [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:nil]; 50 | 51 | self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds]; 52 | [self configureAppearance]; 53 | 54 | ContainerListController *c = [[ContainerListController alloc] init]; 55 | self.window.rootViewController = [[UINavigationController alloc] initWithRootViewController:c]; 56 | [self.window makeKeyAndVisible]; 57 | 58 | return YES; 59 | } 60 | 61 | 62 | - (BOOL) 63 | application:(UIApplication *)application 64 | openURL:(NSURL *)url 65 | sourceApplication:(NSString *)sourceApplication 66 | annotation:(id)annotation 67 | { 68 | if (!url.isFileURL) { 69 | return NO; 70 | } 71 | 72 | NSString *pathSrc = url.path; 73 | 74 | if (![pathSrc.lowercaseString hasSuffix:@".epub"]) { 75 | return NO; 76 | } 77 | 78 | NSString *fileName = pathSrc.lastPathComponent; 79 | NSString *docsPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, 80 | NSUserDomainMask, YES) objectAtIndex:0]; 81 | NSString *pathDst = [docsPath stringByAppendingPathComponent:fileName]; 82 | NSFileManager *fm = [NSFileManager defaultManager]; 83 | 84 | if ([fm fileExistsAtPath:pathDst]) { 85 | return NO; 86 | } 87 | 88 | [fm copyItemAtPath:pathSrc toPath:pathDst error:nil]; 89 | return YES; 90 | } 91 | 92 | 93 | - (void)configureAppearance { 94 | UIColor *color = [UIColor colorWithRed:39/255.0 green:136/255.0 blue:156/255.0 alpha:1]; 95 | 96 | if ([self.window respondsToSelector:@selector(setTintColor:)]) { 97 | self.window.tintColor = color; 98 | } 99 | else { 100 | [[UINavigationBar appearance] setTintColor:color]; 101 | [[UIToolbar appearance] setTintColor:color]; 102 | } 103 | } 104 | 105 | 106 | @end 107 | -------------------------------------------------------------------------------- /Classes/BaseViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // BaseViewController.h 3 | // SDKLauncher-iOS 4 | // 5 | // Created by Shane Meyer on 2/1/13. 6 | // Copyright (c) 2014 Readium Foundation and/or its licensees. All rights reserved. 7 | // 8 | // Redistribution and use in source and binary forms, with or without modification, 9 | // are permitted provided that the following conditions are met: 10 | // 1. Redistributions of source code must retain the above copyright notice, this 11 | // list of conditions and the following disclaimer. 12 | // 2. Redistributions in binary form must reproduce the above copyright notice, 13 | // this list of conditions and the following disclaimer in the documentation and/or 14 | // other materials provided with the distribution. 15 | // 3. Neither the name of the organization nor the names of its contributors may be 16 | // used to endorse or promote products derived from this software without specific 17 | // prior written permission. 18 | // 19 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 20 | // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 | // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 22 | // IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 23 | // INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 24 | // BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 26 | // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 27 | // OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 28 | // OF THE POSSIBILITY OF SUCH DAMAGE. 29 | 30 | #import 31 | 32 | @interface BaseViewController : UIViewController { 33 | @private BOOL m_navBarHidden; 34 | @private BOOL m_visible; 35 | } 36 | 37 | - (void)cleanUp; 38 | - (id)initWithTitle:(NSString *)title navBarHidden:(BOOL)navBarHidden; 39 | 40 | @end 41 | -------------------------------------------------------------------------------- /Classes/BaseViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // BaseViewController.m 3 | // SDKLauncher-iOS 4 | // 5 | // Created by Shane Meyer on 2/1/13. 6 | // Copyright (c) 2014 Readium Foundation and/or its licensees. All rights reserved. 7 | // 8 | // Redistribution and use in source and binary forms, with or without modification, 9 | // are permitted provided that the following conditions are met: 10 | // 1. Redistributions of source code must retain the above copyright notice, this 11 | // list of conditions and the following disclaimer. 12 | // 2. Redistributions in binary form must reproduce the above copyright notice, 13 | // this list of conditions and the following disclaimer in the documentation and/or 14 | // other materials provided with the distribution. 15 | // 3. Neither the name of the organization nor the names of its contributors may be 16 | // used to endorse or promote products derived from this software without specific 17 | // prior written permission. 18 | // 19 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 20 | // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 | // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 22 | // IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 23 | // INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 24 | // BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 26 | // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 27 | // OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 28 | // OF THE POSSIBILITY OF SUCH DAMAGE. 29 | 30 | #import "BaseViewController.h" 31 | 32 | 33 | @implementation BaseViewController 34 | 35 | 36 | - (void)cleanUp { 37 | } 38 | 39 | 40 | - (void)dealloc { 41 | [self cleanUp]; 42 | } 43 | 44 | 45 | - (void)didReceiveMemoryWarning { 46 | [super didReceiveMemoryWarning]; 47 | 48 | if (self.isViewLoaded && !m_visible) { 49 | self.view = nil; 50 | [self cleanUp]; 51 | } 52 | } 53 | 54 | 55 | - (id)initWithTitle:(NSString *)title navBarHidden:(BOOL)navBarHidden { 56 | m_navBarHidden = navBarHidden; 57 | 58 | if (self = [super initWithNibName:nil bundle:nil]) { 59 | self.title = title; 60 | } 61 | 62 | return self; 63 | } 64 | 65 | 66 | - (void)viewDidDisappear:(BOOL)animated { 67 | [super viewDidDisappear:animated]; 68 | m_visible = NO; 69 | } 70 | 71 | 72 | - (void)viewWillAppear:(BOOL)animated { 73 | [super viewWillAppear:animated]; 74 | m_visible = YES; 75 | UINavigationController *navController = self.navigationController; 76 | 77 | if (navController != nil) { 78 | [navController setNavigationBarHidden:m_navBarHidden animated:NO]; 79 | } 80 | } 81 | 82 | 83 | @end 84 | -------------------------------------------------------------------------------- /Classes/Bookmark.h: -------------------------------------------------------------------------------- 1 | // 2 | // Bookmark.h 3 | // SDKLauncher-iOS 4 | // 5 | // Created by Shane Meyer on 4/20/13. 6 | // Copyright (c) 2014 Readium Foundation and/or its licensees. All rights reserved. 7 | // 8 | // Redistribution and use in source and binary forms, with or without modification, 9 | // are permitted provided that the following conditions are met: 10 | // 1. Redistributions of source code must retain the above copyright notice, this 11 | // list of conditions and the following disclaimer. 12 | // 2. Redistributions in binary form must reproduce the above copyright notice, 13 | // this list of conditions and the following disclaimer in the documentation and/or 14 | // other materials provided with the distribution. 15 | // 3. Neither the name of the organization nor the names of its contributors may be 16 | // used to endorse or promote products derived from this software without specific 17 | // prior written permission. 18 | // 19 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 20 | // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 | // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 22 | // IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 23 | // INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 24 | // BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 26 | // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 27 | // OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 28 | // OF THE POSSIBILITY OF SUCH DAMAGE. 29 | 30 | #import 31 | 32 | @interface Bookmark : NSObject { 33 | @private NSString *m_cfi; 34 | @private NSString *m_containerPath; 35 | @private NSString *m_idref; 36 | @private NSString *m_title; 37 | } 38 | 39 | @property (nonatomic, readonly) NSString *cfi; 40 | @property (nonatomic, readonly) NSString *containerPath; 41 | @property (nonatomic, readonly) NSDictionary *dictionary; 42 | @property (nonatomic, readonly) NSString *idref; 43 | @property (nonatomic, readonly) NSString *title; 44 | 45 | - (id) 46 | initWithCFI:(NSString *)cfi 47 | containerPath:(NSString *)containerPath 48 | idref:(NSString *)idref 49 | title:(NSString *)title; 50 | 51 | - (id)initWithDictionary:(NSDictionary *)dictionary; 52 | - (BOOL)isEqualToBookmark:(Bookmark *)bookmark; 53 | 54 | @end 55 | -------------------------------------------------------------------------------- /Classes/Bookmark.m: -------------------------------------------------------------------------------- 1 | // 2 | // Bookmark.m 3 | // SDKLauncher-iOS 4 | // 5 | // Created by Shane Meyer on 4/20/13. 6 | // Copyright (c) 2014 Readium Foundation and/or its licensees. All rights reserved. 7 | // 8 | // Redistribution and use in source and binary forms, with or without modification, 9 | // are permitted provided that the following conditions are met: 10 | // 1. Redistributions of source code must retain the above copyright notice, this 11 | // list of conditions and the following disclaimer. 12 | // 2. Redistributions in binary form must reproduce the above copyright notice, 13 | // this list of conditions and the following disclaimer in the documentation and/or 14 | // other materials provided with the distribution. 15 | // 3. Neither the name of the organization nor the names of its contributors may be 16 | // used to endorse or promote products derived from this software without specific 17 | // prior written permission. 18 | // 19 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 20 | // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 | // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 22 | // IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 23 | // INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 24 | // BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 26 | // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 27 | // OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 28 | // OF THE POSSIBILITY OF SUCH DAMAGE. 29 | 30 | #import "Bookmark.h" 31 | 32 | 33 | #define kKeyCFI @"CFI" 34 | #define kKeyContainerPath @"ContainerPath" 35 | #define kKeyIDRef @"IDRef" 36 | #define kKeyTitle @"Title" 37 | 38 | 39 | @implementation Bookmark 40 | 41 | 42 | @synthesize cfi = m_cfi; 43 | @synthesize containerPath = m_containerPath; 44 | @synthesize idref = m_idref; 45 | @synthesize title = m_title; 46 | 47 | 48 | - (NSString *)description { 49 | return [@"Bookmark " stringByAppendingString:self.dictionary.description]; 50 | } 51 | 52 | 53 | - (NSDictionary *)dictionary { 54 | return @{ 55 | kKeyCFI : m_cfi, 56 | kKeyContainerPath : m_containerPath, 57 | kKeyIDRef : m_idref, 58 | kKeyTitle : m_title 59 | }; 60 | } 61 | 62 | 63 | - (id) 64 | initWithCFI:(NSString *)cfi 65 | containerPath:(NSString *)containerPath 66 | idref:(NSString *)idref 67 | title:(NSString *)title 68 | { 69 | if (cfi == nil || 70 | cfi.length == 0 || 71 | containerPath == nil || 72 | containerPath.length == 0 || 73 | idref == nil || 74 | idref.length == 0) 75 | { 76 | return nil; 77 | } 78 | 79 | if (title == nil) { 80 | title = @""; 81 | } 82 | 83 | if (self = [super init]) { 84 | m_cfi = cfi; 85 | m_containerPath = containerPath; 86 | m_idref = idref; 87 | m_title = title; 88 | } 89 | 90 | return self; 91 | } 92 | 93 | 94 | - (id)initWithDictionary:(NSDictionary *)dictionary { 95 | if (dictionary == nil) { 96 | return nil; 97 | } 98 | 99 | return [self 100 | initWithCFI:[dictionary objectForKey:kKeyCFI] 101 | containerPath:[dictionary objectForKey:kKeyContainerPath] 102 | idref:[dictionary objectForKey:kKeyIDRef] 103 | title:[dictionary objectForKey:kKeyTitle]]; 104 | } 105 | 106 | 107 | - (BOOL)isEqualToBookmark:(Bookmark *)bookmark { 108 | return 109 | bookmark != nil && 110 | [bookmark.cfi isEqualToString:m_cfi] && 111 | [bookmark.containerPath isEqualToString:m_containerPath] && 112 | [bookmark.idref isEqualToString:m_idref] && 113 | [bookmark.title isEqualToString:m_title]; 114 | } 115 | 116 | 117 | @end 118 | -------------------------------------------------------------------------------- /Classes/BookmarkDatabase.h: -------------------------------------------------------------------------------- 1 | // 2 | // BookmarkDatabase.h 3 | // SDKLauncher-iOS 4 | // 5 | // Created by Shane Meyer on 4/20/13. 6 | // Copyright (c) 2014 Readium Foundation and/or its licensees. All rights reserved. 7 | // 8 | // Redistribution and use in source and binary forms, with or without modification, 9 | // are permitted provided that the following conditions are met: 10 | // 1. Redistributions of source code must retain the above copyright notice, this 11 | // list of conditions and the following disclaimer. 12 | // 2. Redistributions in binary form must reproduce the above copyright notice, 13 | // this list of conditions and the following disclaimer in the documentation and/or 14 | // other materials provided with the distribution. 15 | // 3. Neither the name of the organization nor the names of its contributors may be 16 | // used to endorse or promote products derived from this software without specific 17 | // prior written permission. 18 | // 19 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 20 | // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 | // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 22 | // IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 23 | // INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 24 | // BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 26 | // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 27 | // OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 28 | // OF THE POSSIBILITY OF SUCH DAMAGE. 29 | 30 | #import 31 | 32 | @class Bookmark; 33 | 34 | @interface BookmarkDatabase : NSObject 35 | 36 | - (void)addBookmark:(Bookmark *)bookmark; 37 | - (NSArray *)bookmarksForContainerPath:(NSString *)containerPath; 38 | - (void)deleteBookmark:(Bookmark *)bookmark; 39 | + (BookmarkDatabase *)shared; 40 | 41 | @end 42 | -------------------------------------------------------------------------------- /Classes/BookmarkDatabase.m: -------------------------------------------------------------------------------- 1 | // 2 | // BookmarkDatabase.m 3 | // SDKLauncher-iOS 4 | // 5 | // Created by Shane Meyer on 4/20/13. 6 | // Copyright (c) 2014 Readium Foundation and/or its licensees. All rights reserved. 7 | // 8 | // Redistribution and use in source and binary forms, with or without modification, 9 | // are permitted provided that the following conditions are met: 10 | // 1. Redistributions of source code must retain the above copyright notice, this 11 | // list of conditions and the following disclaimer. 12 | // 2. Redistributions in binary form must reproduce the above copyright notice, 13 | // this list of conditions and the following disclaimer in the documentation and/or 14 | // other materials provided with the distribution. 15 | // 3. Neither the name of the organization nor the names of its contributors may be 16 | // used to endorse or promote products derived from this software without specific 17 | // prior written permission. 18 | // 19 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 20 | // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 | // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 22 | // IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 23 | // INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 24 | // BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 26 | // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 27 | // OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 28 | // OF THE POSSIBILITY OF SUCH DAMAGE. 29 | 30 | #import "BookmarkDatabase.h" 31 | #import "Bookmark.h" 32 | #import "Settings.h" 33 | 34 | 35 | @implementation BookmarkDatabase 36 | 37 | 38 | - (void)addBookmark:(Bookmark *)bookmark { 39 | if (bookmark != nil) { 40 | NSMutableDictionary *dict = [NSMutableDictionary dictionaryWithDictionary: 41 | [Settings shared].bookmarks]; 42 | NSMutableArray *array = [NSMutableArray arrayWithArray: 43 | [dict objectForKey:bookmark.containerPath]]; 44 | [dict setObject:array forKey:bookmark.containerPath]; 45 | [array addObject:bookmark.dictionary]; 46 | [Settings shared].bookmarks = dict; 47 | } 48 | } 49 | 50 | 51 | - (NSArray *)bookmarksForContainerPath:(NSString *)containerPath { 52 | NSMutableArray *bookmarks = [NSMutableArray array]; 53 | 54 | if (containerPath != nil && containerPath.length > 0) { 55 | for (NSDictionary *dict in [[Settings shared].bookmarks objectForKey:containerPath]) { 56 | Bookmark *b = [[Bookmark alloc] initWithDictionary:dict]; 57 | 58 | if (b == nil) { 59 | NSLog(@"The bookmark is nil!"); 60 | } 61 | else { 62 | [bookmarks addObject:b]; 63 | } 64 | } 65 | } 66 | 67 | return bookmarks; 68 | } 69 | 70 | 71 | - (void)deleteBookmark:(Bookmark *)bookmark { 72 | if (bookmark == nil) { 73 | return; 74 | } 75 | 76 | NSMutableDictionary *dict = [NSMutableDictionary dictionaryWithDictionary: 77 | [Settings shared].bookmarks]; 78 | NSMutableArray *array = [NSMutableArray arrayWithArray: 79 | [dict objectForKey:bookmark.containerPath]]; 80 | [dict setObject:array forKey:bookmark.containerPath]; 81 | 82 | for (int i = 0; i < array.count; i++) { 83 | NSDictionary *d = [array objectAtIndex:i]; 84 | Bookmark *b = [[Bookmark alloc] initWithDictionary:d]; 85 | 86 | if (b == nil) { 87 | NSLog(@"The bookmark is nil!"); 88 | } 89 | else if ([bookmark isEqualToBookmark:b]) { 90 | [array removeObjectAtIndex:i]; 91 | [Settings shared].bookmarks = dict; 92 | return; 93 | } 94 | } 95 | } 96 | 97 | 98 | + (BookmarkDatabase *)shared { 99 | static BookmarkDatabase *shared = nil; 100 | 101 | if (shared == nil) { 102 | shared = [[BookmarkDatabase alloc] init]; 103 | } 104 | 105 | return shared; 106 | } 107 | 108 | 109 | @end 110 | -------------------------------------------------------------------------------- /Classes/BookmarkListController.h: -------------------------------------------------------------------------------- 1 | // 2 | // BookmarkListController.h 3 | // SDKLauncher-iOS 4 | // 5 | // Created by Shane Meyer on 4/20/13. 6 | // Copyright (c) 2014 Readium Foundation and/or its licensees. All rights reserved. 7 | // 8 | // Redistribution and use in source and binary forms, with or without modification, 9 | // are permitted provided that the following conditions are met: 10 | // 1. Redistributions of source code must retain the above copyright notice, this 11 | // list of conditions and the following disclaimer. 12 | // 2. Redistributions in binary form must reproduce the above copyright notice, 13 | // this list of conditions and the following disclaimer in the documentation and/or 14 | // other materials provided with the distribution. 15 | // 3. Neither the name of the organization nor the names of its contributors may be 16 | // used to endorse or promote products derived from this software without specific 17 | // prior written permission. 18 | // 19 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 20 | // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 | // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 22 | // IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 23 | // INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 24 | // BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 26 | // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 27 | // OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 28 | // OF THE POSSIBILITY OF SUCH DAMAGE. 29 | 30 | #import "BaseViewController.h" 31 | 32 | @class RDContainer; 33 | @class RDPackage; 34 | 35 | @interface BookmarkListController : BaseViewController < 36 | UITableViewDataSource, 37 | UITableViewDelegate> 38 | { 39 | @private NSArray *m_bookmarks; 40 | @private RDContainer *m_container; 41 | @private RDPackage *m_package; 42 | @private __weak UITableView *m_table; 43 | } 44 | 45 | - (id)initWithContainer:(RDContainer *)container package:(RDPackage *)package; 46 | 47 | @end 48 | -------------------------------------------------------------------------------- /Classes/BookmarkListController.m: -------------------------------------------------------------------------------- 1 | // 2 | // BookmarkListController.m 3 | // SDKLauncher-iOS 4 | // 5 | // Created by Shane Meyer on 4/20/13. 6 | // Copyright (c) 2014 Readium Foundation and/or its licensees. All rights reserved. 7 | // 8 | // Redistribution and use in source and binary forms, with or without modification, 9 | // are permitted provided that the following conditions are met: 10 | // 1. Redistributions of source code must retain the above copyright notice, this 11 | // list of conditions and the following disclaimer. 12 | // 2. Redistributions in binary form must reproduce the above copyright notice, 13 | // this list of conditions and the following disclaimer in the documentation and/or 14 | // other materials provided with the distribution. 15 | // 3. Neither the name of the organization nor the names of its contributors may be 16 | // used to endorse or promote products derived from this software without specific 17 | // prior written permission. 18 | // 19 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 20 | // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 | // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 22 | // IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 23 | // INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 24 | // BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 26 | // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 27 | // OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 28 | // OF THE POSSIBILITY OF SUCH DAMAGE. 29 | 30 | #import "BookmarkListController.h" 31 | #import "Bookmark.h" 32 | #import "BookmarkDatabase.h" 33 | #import "EPubViewController.h" 34 | #import "RDContainer.h" 35 | #import "RDPackage.h" 36 | 37 | 38 | @interface BookmarkListController() 39 | 40 | - (void)updateEditDoneButton; 41 | 42 | @end 43 | 44 | 45 | @implementation BookmarkListController 46 | 47 | 48 | - (id)initWithContainer:(RDContainer *)container package:(RDPackage *)package { 49 | if (container == nil || package == nil) { 50 | return nil; 51 | } 52 | 53 | if (self = [super initWithTitle:LocStr(@"BOOKMARKS") navBarHidden:NO]) { 54 | m_bookmarks = [[BookmarkDatabase shared] bookmarksForContainerPath:container.path]; 55 | m_container = container; 56 | m_package = package; 57 | } 58 | 59 | return self; 60 | } 61 | 62 | 63 | - (void)loadView { 64 | self.view = [[UIView alloc] init]; 65 | 66 | UITableView *table = [[UITableView alloc] initWithFrame:CGRectZero style:UITableViewStylePlain]; 67 | m_table = table; 68 | table.dataSource = self; 69 | table.delegate = self; 70 | [self.view addSubview:table]; 71 | 72 | [self updateEditDoneButton]; 73 | } 74 | 75 | 76 | - (void)onClickDone { 77 | [m_table setEditing:NO animated:YES]; 78 | [self updateEditDoneButton]; 79 | } 80 | 81 | 82 | - (void)onClickEdit { 83 | [m_table setEditing:YES animated:YES]; 84 | [self updateEditDoneButton]; 85 | } 86 | 87 | 88 | - (UITableViewCell *) 89 | tableView:(UITableView *)tableView 90 | cellForRowAtIndexPath:(NSIndexPath *)indexPath 91 | { 92 | UITableViewCell *cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault 93 | reuseIdentifier:nil]; 94 | cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator; 95 | Bookmark *bookmark = [m_bookmarks objectAtIndex:indexPath.row]; 96 | cell.textLabel.text = bookmark.title; 97 | return cell; 98 | } 99 | 100 | 101 | - (void) 102 | tableView:(UITableView *)tableView 103 | commitEditingStyle:(UITableViewCellEditingStyle)editingStyle 104 | forRowAtIndexPath:(NSIndexPath *)indexPath 105 | { 106 | if (editingStyle == UITableViewCellEditingStyleDelete) { 107 | Bookmark *bookmark = [m_bookmarks objectAtIndex:indexPath.row]; 108 | [[BookmarkDatabase shared] deleteBookmark:bookmark]; 109 | 110 | m_bookmarks = [[BookmarkDatabase shared] bookmarksForContainerPath:m_container.path]; 111 | 112 | [tableView deleteRowsAtIndexPaths:@[ indexPath ] 113 | withRowAnimation:UITableViewRowAnimationAutomatic]; 114 | 115 | // Rather than update the edit/done button immediately, wait one run loop cycle. If 116 | // a swipe gesture triggered this delete and we updated the edit/done button 117 | // immediately, we would be found to still be in edit mode, which wouldn't be right. 118 | 119 | [self performSelector:@selector(updateEditDoneButton) withObject:nil afterDelay:0]; 120 | } 121 | } 122 | 123 | 124 | - (void) 125 | tableView:(UITableView *)tableView 126 | didSelectRowAtIndexPath:(NSIndexPath *)indexPath 127 | { 128 | Bookmark *bookmark = [m_bookmarks objectAtIndex:indexPath.row]; 129 | 130 | EPubViewController *c = [[EPubViewController alloc] 131 | initWithContainer:m_container 132 | package:m_package 133 | bookmark:bookmark]; 134 | 135 | if (c != nil) { 136 | [self.navigationController pushViewController:c animated:YES]; 137 | } 138 | } 139 | 140 | 141 | - (NSInteger) 142 | tableView:(UITableView *)tableView 143 | numberOfRowsInSection:(NSInteger)section 144 | { 145 | return m_bookmarks.count; 146 | } 147 | 148 | 149 | - (void)updateEditDoneButton { 150 | if (m_bookmarks.count == 0 || m_table == nil) { 151 | self.navigationItem.rightBarButtonItem = nil; 152 | } 153 | else if (m_table.isEditing) { 154 | self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] 155 | initWithBarButtonSystemItem:UIBarButtonSystemItemDone 156 | target:self 157 | action:@selector(onClickDone)]; 158 | } 159 | else { 160 | self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] 161 | initWithBarButtonSystemItem:UIBarButtonSystemItemEdit 162 | target:self 163 | action:@selector(onClickEdit)]; 164 | } 165 | } 166 | 167 | 168 | - (void)viewDidLayoutSubviews { 169 | m_table.frame = self.view.bounds; 170 | } 171 | 172 | 173 | - (void)viewWillAppear:(BOOL)animated { 174 | [super viewWillAppear:animated]; 175 | NSArray *bookmarks = [[BookmarkDatabase shared] bookmarksForContainerPath:m_container.path]; 176 | 177 | if (bookmarks.count == m_bookmarks.count) { 178 | if (m_table.indexPathForSelectedRow != nil) { 179 | [m_table deselectRowAtIndexPath:m_table.indexPathForSelectedRow animated:YES]; 180 | } 181 | } 182 | else { 183 | m_bookmarks = bookmarks; 184 | [m_table reloadData]; 185 | } 186 | } 187 | 188 | 189 | @end 190 | -------------------------------------------------------------------------------- /Classes/ContainerController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ContainerController.h 3 | // SDKLauncher-iOS 4 | // 5 | // Created by Shane Meyer on 2/4/13. 6 | // Copyright (c) 2014 Readium Foundation and/or its licensees. All rights reserved. 7 | // 8 | // Redistribution and use in source and binary forms, with or without modification, 9 | // are permitted provided that the following conditions are met: 10 | // 1. Redistributions of source code must retain the above copyright notice, this 11 | // list of conditions and the following disclaimer. 12 | // 2. Redistributions in binary form must reproduce the above copyright notice, 13 | // this list of conditions and the following disclaimer in the documentation and/or 14 | // other materials provided with the distribution. 15 | // 3. Neither the name of the organization nor the names of its contributors may be 16 | // used to endorse or promote products derived from this software without specific 17 | // prior written permission. 18 | // 19 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 20 | // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 | // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 22 | // IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 23 | // INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 24 | // BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 26 | // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 27 | // OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 28 | // OF THE POSSIBILITY OF SUCH DAMAGE. 29 | 30 | #import "BaseViewController.h" 31 | 32 | @interface ContainerController : BaseViewController 33 | 34 | - (instancetype)initWithPath:(NSString *)path; 35 | 36 | @end 37 | -------------------------------------------------------------------------------- /Classes/ContainerController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ContainerController.m 3 | // SDKLauncher-iOS 4 | // 5 | // Created by Shane Meyer on 2/4/13. 6 | // Copyright (c) 2014 Readium Foundation and/or its licensees. All rights reserved. 7 | // 8 | // Redistribution and use in source and binary forms, with or without modification, 9 | // are permitted provided that the following conditions are met: 10 | // 1. Redistributions of source code must retain the above copyright notice, this 11 | // list of conditions and the following disclaimer. 12 | // 2. Redistributions in binary form must reproduce the above copyright notice, 13 | // this list of conditions and the following disclaimer in the documentation and/or 14 | // other materials provided with the distribution. 15 | // 3. Neither the name of the organization nor the names of its contributors may be 16 | // used to endorse or promote products derived from this software without specific 17 | // prior written permission. 18 | // 19 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 20 | // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 | // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 22 | // IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 23 | // INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 24 | // BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 26 | // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 27 | // OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 28 | // OF THE POSSIBILITY OF SUCH DAMAGE. 29 | 30 | #import "ContainerController.h" 31 | #import "BookmarkDatabase.h" 32 | #import "BookmarkListController.h" 33 | #import "NavigationElementController.h" 34 | #import "PackageMetadataController.h" 35 | #import "RDContainer.h" 36 | #import "RDPackage.h" 37 | #import "SpineItemListController.h" 38 | 39 | 40 | @interface ContainerController () < 41 | RDContainerDelegate, 42 | UITableViewDataSource, 43 | UITableViewDelegate, 44 | UIAlertViewDelegate> 45 | { 46 | @private RDContainer *m_container; 47 | @private RDPackage *m_package; 48 | @private __weak UITableView *m_table; 49 | @private NSMutableArray *m_sdkErrorMessages; 50 | } 51 | 52 | @end 53 | 54 | 55 | @implementation ContainerController 56 | 57 | - (BOOL)container:(RDContainer *)container handleSdkError:(NSString *)message isSevereEpubError:(BOOL)isSevereEpubError { 58 | 59 | NSLog(@"READIUM SDK: %@\n", message); 60 | 61 | if (isSevereEpubError == YES) 62 | [m_sdkErrorMessages addObject:message]; 63 | 64 | // never throws an exception 65 | return YES; 66 | } 67 | 68 | - (void) popErrorMessage 69 | { 70 | NSInteger count = [m_sdkErrorMessages count]; 71 | if (count > 0) 72 | { 73 | __block NSString *message = [m_sdkErrorMessages firstObject]; 74 | [m_sdkErrorMessages removeObjectAtIndex:0]; 75 | 76 | dispatch_async(dispatch_get_main_queue(), ^{ 77 | 78 | UIAlertView * alert =[[UIAlertView alloc] 79 | initWithTitle:@"EPUB warning" 80 | message:message 81 | delegate: self 82 | cancelButtonTitle:@"Ignore all" 83 | otherButtonTitles: nil]; 84 | [alert addButtonWithTitle:@"Ignore"]; 85 | [alert show]; 86 | }); 87 | } 88 | } 89 | 90 | - (void) alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex 91 | { 92 | if (buttonIndex != [alertView cancelButtonIndex]) 93 | { 94 | [self popErrorMessage]; 95 | } 96 | } 97 | 98 | - (instancetype)initWithPath:(NSString *)path { 99 | if (self = [super initWithTitle:nil navBarHidden:NO]) { 100 | 101 | m_sdkErrorMessages = [[NSMutableArray alloc] initWithCapacity:0]; 102 | 103 | m_container = [[RDContainer alloc] initWithDelegate:self path:path]; 104 | 105 | m_package = m_container.firstPackage; 106 | 107 | [self popErrorMessage]; 108 | 109 | if (m_package == nil) { 110 | return nil; 111 | } 112 | 113 | NSArray *components = path.pathComponents; 114 | self.title = (components == nil || components.count == 0) ? @"" : components.lastObject; 115 | } 116 | 117 | return self; 118 | } 119 | 120 | 121 | - (void)loadView { 122 | self.view = [[UIView alloc] init]; 123 | 124 | UITableView *table = [[UITableView alloc] initWithFrame:CGRectZero style:UITableViewStyleGrouped]; 125 | m_table = table; 126 | table.dataSource = self; 127 | table.delegate = self; 128 | [self.view addSubview:table]; 129 | } 130 | 131 | 132 | - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { 133 | return 3; 134 | } 135 | 136 | 137 | - (UITableViewCell *) 138 | tableView:(UITableView *)tableView 139 | cellForRowAtIndexPath:(NSIndexPath *)indexPath 140 | { 141 | UITableViewCell *cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault 142 | reuseIdentifier:nil]; 143 | cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator; 144 | 145 | if (indexPath.section == 0) { 146 | if (indexPath.row == 0) { 147 | cell.textLabel.text = LocStr(@"METADATA"); 148 | } 149 | else if (indexPath.row == 1) { 150 | cell.textLabel.text = LocStr(@"SPINE_ITEMS"); 151 | } 152 | } 153 | else if (indexPath.section == 1) { 154 | if (indexPath.row == 0) { 155 | cell.textLabel.text = LocStr(@"LIST_OF_FIGURES"); 156 | } 157 | else if (indexPath.row == 1) { 158 | cell.textLabel.text = LocStr(@"LIST_OF_ILLUSTRATIONS"); 159 | } 160 | else if (indexPath.row == 2) { 161 | cell.textLabel.text = LocStr(@"LIST_OF_TABLES"); 162 | } 163 | else if (indexPath.row == 3) { 164 | cell.textLabel.text = LocStr(@"PAGE_LIST"); 165 | } 166 | else if (indexPath.row == 4) { 167 | cell.textLabel.text = LocStr(@"TABLE_OF_CONTENTS"); 168 | } 169 | } 170 | else if (indexPath.section == 2) { 171 | if (indexPath.row == 0) { 172 | cell.textLabel.text = LocStr(@"BOOKMARKS_WITH_COUNT", [[BookmarkDatabase shared] 173 | bookmarksForContainerPath:m_container.path].count); 174 | } 175 | } 176 | 177 | return cell; 178 | } 179 | 180 | 181 | - (void) 182 | tableView:(UITableView *)tableView 183 | didSelectRowAtIndexPath:(NSIndexPath *)indexPath 184 | { 185 | if (indexPath.section == 0) { 186 | if (indexPath.row == 0) { 187 | PackageMetadataController *c = [[PackageMetadataController alloc] 188 | initWithPackage:m_package]; 189 | [self.navigationController pushViewController:c animated:YES]; 190 | } 191 | else if (indexPath.row == 1) { 192 | SpineItemListController *c = [[SpineItemListController alloc] 193 | initWithContainer:m_container package:m_package]; 194 | [self.navigationController pushViewController:c animated:YES]; 195 | } 196 | } 197 | else if (indexPath.section == 1) { 198 | NavigationElementController *c = nil; 199 | NSString *title = [tableView cellForRowAtIndexPath:indexPath].textLabel.text; 200 | 201 | if (indexPath.row == 0) { 202 | c = [[NavigationElementController alloc] 203 | initWithNavigationElement:m_package.listOfFigures 204 | container:m_container 205 | package:m_package 206 | title:title]; 207 | } 208 | else if (indexPath.row == 1) { 209 | c = [[NavigationElementController alloc] 210 | initWithNavigationElement:m_package.listOfIllustrations 211 | container:m_container 212 | package:m_package 213 | title:title]; 214 | } 215 | else if (indexPath.row == 2) { 216 | c = [[NavigationElementController alloc] 217 | initWithNavigationElement:m_package.listOfTables 218 | container:m_container 219 | package:m_package 220 | title:title]; 221 | } 222 | else if (indexPath.row == 3) { 223 | c = [[NavigationElementController alloc] 224 | initWithNavigationElement:m_package.pageList 225 | container:m_container 226 | package:m_package 227 | title:title]; 228 | } 229 | else if (indexPath.row == 4) { 230 | c = [[NavigationElementController alloc] 231 | initWithNavigationElement:m_package.tableOfContents 232 | container:m_container 233 | package:m_package 234 | title:title]; 235 | } 236 | 237 | if (c == nil) { 238 | [m_table deselectRowAtIndexPath:indexPath animated:YES]; 239 | } 240 | else { 241 | [self.navigationController pushViewController:c animated:YES]; 242 | } 243 | } 244 | if (indexPath.section == 2) { 245 | if (indexPath.row == 0) { 246 | BookmarkListController *c = [[BookmarkListController alloc] 247 | initWithContainer:m_container package:m_package]; 248 | 249 | if (c != nil) { 250 | [self.navigationController pushViewController:c animated:YES]; 251 | } 252 | } 253 | } 254 | } 255 | 256 | 257 | - (NSInteger) 258 | tableView:(UITableView *)tableView 259 | numberOfRowsInSection:(NSInteger)section 260 | { 261 | return 262 | section == 0 ? 2 : 263 | section == 1 ? 5 : 264 | section == 2 ? 1 : 0; 265 | } 266 | 267 | 268 | - (void)viewDidLayoutSubviews { 269 | m_table.frame = self.view.bounds; 270 | } 271 | 272 | 273 | - (void)viewWillAppear:(BOOL)animated { 274 | [super viewWillAppear:animated]; 275 | 276 | if (m_table.indexPathForSelectedRow != nil) { 277 | [m_table deselectRowAtIndexPath:m_table.indexPathForSelectedRow animated:YES]; 278 | } 279 | 280 | // Bookmarks may have been added since we were last visible, so update the bookmark 281 | // count within the cell if needed. 282 | 283 | for (UITableViewCell *cell in m_table.visibleCells) { 284 | NSIndexPath *indexPath = [m_table indexPathForCell:cell]; 285 | 286 | if (indexPath.section == 2 && indexPath.row == 0) { 287 | cell.textLabel.text = LocStr(@"BOOKMARKS_WITH_COUNT", [[BookmarkDatabase shared] 288 | bookmarksForContainerPath:m_container.path].count); 289 | } 290 | } 291 | } 292 | 293 | 294 | @end 295 | -------------------------------------------------------------------------------- /Classes/ContainerList.h: -------------------------------------------------------------------------------- 1 | // 2 | // ContainerList.h 3 | // SDKLauncher-iOS 4 | // 5 | // Created by Shane Meyer on 2/1/13. 6 | // Copyright (c) 2014 Readium Foundation and/or its licensees. All rights reserved. 7 | // 8 | // Redistribution and use in source and binary forms, with or without modification, 9 | // are permitted provided that the following conditions are met: 10 | // 1. Redistributions of source code must retain the above copyright notice, this 11 | // list of conditions and the following disclaimer. 12 | // 2. Redistributions in binary form must reproduce the above copyright notice, 13 | // this list of conditions and the following disclaimer in the documentation and/or 14 | // other materials provided with the distribution. 15 | // 3. Neither the name of the organization nor the names of its contributors may be 16 | // used to endorse or promote products derived from this software without specific 17 | // prior written permission. 18 | // 19 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 20 | // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 | // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 22 | // IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 23 | // INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 24 | // BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 26 | // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 27 | // OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 28 | // OF THE POSSIBILITY OF SUCH DAMAGE. 29 | 30 | #import 31 | 32 | extern NSString * const kSDKLauncherContainerListDidChange; 33 | 34 | @interface ContainerList : NSObject { 35 | @private NSArray *m_paths; 36 | } 37 | 38 | @property (nonatomic, readonly) NSArray *paths; 39 | 40 | + (ContainerList *)shared; 41 | 42 | @end 43 | -------------------------------------------------------------------------------- /Classes/ContainerList.m: -------------------------------------------------------------------------------- 1 | // 2 | // ContainerList.m 3 | // SDKLauncher-iOS 4 | // 5 | // Created by Shane Meyer on 2/1/13. 6 | // Copyright (c) 2014 Readium Foundation and/or its licensees. All rights reserved. 7 | // 8 | // Redistribution and use in source and binary forms, with or without modification, 9 | // are permitted provided that the following conditions are met: 10 | // 1. Redistributions of source code must retain the above copyright notice, this 11 | // list of conditions and the following disclaimer. 12 | // 2. Redistributions in binary form must reproduce the above copyright notice, 13 | // this list of conditions and the following disclaimer in the documentation and/or 14 | // other materials provided with the distribution. 15 | // 3. Neither the name of the organization nor the names of its contributors may be 16 | // used to endorse or promote products derived from this software without specific 17 | // prior written permission. 18 | // 19 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 20 | // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 | // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 22 | // IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 23 | // INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 24 | // BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 26 | // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 27 | // OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 28 | // OF THE POSSIBILITY OF SUCH DAMAGE. 29 | 30 | #import "ContainerList.h" 31 | 32 | 33 | NSString * const kSDKLauncherContainerListDidChange = @"SDKLauncherContainerListDidChange"; 34 | 35 | 36 | @implementation ContainerList 37 | 38 | 39 | - (void)checkForChanges { 40 | NSArray *pathsCurr = self.paths; 41 | BOOL didChange = NO; 42 | 43 | NSUInteger countCurr = pathsCurr.count; 44 | NSUInteger countPrev = (m_paths == nil) ? 0 : m_paths.count; 45 | 46 | if (countCurr != countPrev) { 47 | didChange = YES; 48 | } 49 | else if (countCurr > 0) { 50 | for (NSUInteger i = 0; i < countCurr; i++) { 51 | NSString *pathCurr = [pathsCurr objectAtIndex:i]; 52 | NSString *pathPrev = [m_paths objectAtIndex:i]; 53 | 54 | if (![pathCurr isEqualToString:pathPrev]) { 55 | didChange = YES; 56 | break; 57 | } 58 | } 59 | } 60 | 61 | if (didChange) { 62 | m_paths = pathsCurr; 63 | [[NSNotificationCenter defaultCenter] postNotificationName: 64 | kSDKLauncherContainerListDidChange object:self]; 65 | } 66 | 67 | [self performSelector:@selector(checkForChanges) withObject:nil afterDelay:1]; 68 | } 69 | 70 | 71 | - (id)init { 72 | if (self = [super init]) { 73 | NSString *resPath = [NSBundle mainBundle].resourcePath; 74 | NSString *docsPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, 75 | NSUserDomainMask, YES) objectAtIndex:0]; 76 | NSFileManager *fm = [NSFileManager defaultManager]; 77 | 78 | for (NSString *fileName in [fm contentsOfDirectoryAtPath:resPath error:nil]) { 79 | if ([fileName.lowercaseString hasSuffix:@".epub"]) { 80 | NSString *src = [resPath stringByAppendingPathComponent:fileName]; 81 | NSString *dst = [docsPath stringByAppendingPathComponent:fileName]; 82 | 83 | if (![fm fileExistsAtPath:dst]) { 84 | [fm copyItemAtPath:src toPath:dst error:nil]; 85 | } 86 | } 87 | } 88 | 89 | m_paths = self.paths; 90 | [self performSelector:@selector(checkForChanges) withObject:nil afterDelay:0]; 91 | } 92 | 93 | return self; 94 | } 95 | 96 | 97 | - (NSArray *)paths { 98 | NSMutableArray *paths = [NSMutableArray arrayWithCapacity:16]; 99 | 100 | NSString *docsPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, 101 | NSUserDomainMask, YES) objectAtIndex:0]; 102 | NSFileManager *fm = [NSFileManager defaultManager]; 103 | 104 | for (NSString *fileName in [fm contentsOfDirectoryAtPath:docsPath error:nil]) { 105 | if ([fileName.lowercaseString hasSuffix:@".epub"]) { 106 | [paths addObject:[docsPath stringByAppendingPathComponent:fileName]]; 107 | } 108 | } 109 | 110 | [paths sortUsingComparator:^NSComparisonResult(NSString *path0, NSString *path1) { 111 | return [path0 compare:path1]; 112 | }]; 113 | 114 | return paths; 115 | } 116 | 117 | 118 | + (ContainerList *)shared { 119 | static ContainerList *shared = nil; 120 | 121 | if (shared == nil) { 122 | shared = [[ContainerList alloc] init]; 123 | } 124 | 125 | return shared; 126 | } 127 | 128 | 129 | @end 130 | -------------------------------------------------------------------------------- /Classes/ContainerListController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ContainerListController.h 3 | // SDKLauncher-iOS 4 | // 5 | // Created by Shane Meyer on 2/1/13. 6 | // Copyright (c) 2014 Readium Foundation and/or its licensees. All rights reserved. 7 | // 8 | // Redistribution and use in source and binary forms, with or without modification, 9 | // are permitted provided that the following conditions are met: 10 | // 1. Redistributions of source code must retain the above copyright notice, this 11 | // list of conditions and the following disclaimer. 12 | // 2. Redistributions in binary form must reproduce the above copyright notice, 13 | // this list of conditions and the following disclaimer in the documentation and/or 14 | // other materials provided with the distribution. 15 | // 3. Neither the name of the organization nor the names of its contributors may be 16 | // used to endorse or promote products derived from this software without specific 17 | // prior written permission. 18 | // 19 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 20 | // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 | // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 22 | // IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 23 | // INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 24 | // BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 26 | // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 27 | // OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 28 | // OF THE POSSIBILITY OF SUCH DAMAGE. 29 | 30 | #import "BaseViewController.h" 31 | 32 | @interface ContainerListController : BaseViewController < 33 | UITableViewDataSource, 34 | UITableViewDelegate> 35 | { 36 | @private NSArray *m_paths; 37 | @private __weak UITableView *m_table; 38 | } 39 | 40 | @end 41 | -------------------------------------------------------------------------------- /Classes/ContainerListController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ContainerListController.m 3 | // SDKLauncher-iOS 4 | // 5 | // Created by Shane Meyer on 2/1/13. 6 | // Copyright (c) 2014 Readium Foundation and/or its licensees. All rights reserved. 7 | // 8 | // Redistribution and use in source and binary forms, with or without modification, 9 | // are permitted provided that the following conditions are met: 10 | // 1. Redistributions of source code must retain the above copyright notice, this 11 | // list of conditions and the following disclaimer. 12 | // 2. Redistributions in binary form must reproduce the above copyright notice, 13 | // this list of conditions and the following disclaimer in the documentation and/or 14 | // other materials provided with the distribution. 15 | // 3. Neither the name of the organization nor the names of its contributors may be 16 | // used to endorse or promote products derived from this software without specific 17 | // prior written permission. 18 | // 19 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 20 | // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 | // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 22 | // IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 23 | // INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 24 | // BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 26 | // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 27 | // OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 28 | // OF THE POSSIBILITY OF SUCH DAMAGE. 29 | 30 | #import "ContainerListController.h" 31 | #import "ContainerController.h" 32 | #import "ContainerList.h" 33 | 34 | 35 | @implementation ContainerListController 36 | 37 | 38 | - (void)dealloc { 39 | [[NSNotificationCenter defaultCenter] removeObserver:self]; 40 | } 41 | 42 | 43 | - (id)init { 44 | if (self = [super initWithTitle:LocStr(@"CONTAINER_LIST_TITLE") navBarHidden:NO]) { 45 | m_paths = [ContainerList shared].paths; 46 | 47 | [[NSNotificationCenter defaultCenter] addObserver:self 48 | selector:@selector(onContainerListDidChange) 49 | name:kSDKLauncherContainerListDidChange object:nil]; 50 | } 51 | 52 | return self; 53 | } 54 | 55 | 56 | - (void)loadView { 57 | self.view = [[UIView alloc] init]; 58 | 59 | UITableView *table = [[UITableView alloc] initWithFrame:CGRectZero style:UITableViewStylePlain]; 60 | m_table = table; 61 | table.dataSource = self; 62 | table.delegate = self; 63 | [self.view addSubview:table]; 64 | } 65 | 66 | 67 | - (void)onContainerListDidChange { 68 | m_paths = [ContainerList shared].paths; 69 | [m_table reloadData]; 70 | } 71 | 72 | 73 | - (UITableViewCell *) 74 | tableView:(UITableView *)tableView 75 | cellForRowAtIndexPath:(NSIndexPath *)indexPath 76 | { 77 | UITableViewCell *cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault 78 | reuseIdentifier:nil]; 79 | cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator; 80 | NSString *path = [m_paths objectAtIndex:indexPath.row]; 81 | NSArray *components = path.pathComponents; 82 | cell.textLabel.text = (components == nil || components.count == 0) ? 83 | @"" : components.lastObject; 84 | return cell; 85 | } 86 | 87 | 88 | - (void) 89 | tableView:(UITableView *)tableView 90 | didSelectRowAtIndexPath:(NSIndexPath *)indexPath 91 | { 92 | [tableView deselectRowAtIndexPath:indexPath animated:YES]; 93 | NSString *path = [m_paths objectAtIndex:indexPath.row]; 94 | ContainerController *c = [[ContainerController alloc] initWithPath:path]; 95 | 96 | if (c != nil) { 97 | [self.navigationController pushViewController:c animated:YES]; 98 | } 99 | } 100 | 101 | 102 | - (NSInteger) 103 | tableView:(UITableView *)tableView 104 | numberOfRowsInSection:(NSInteger)section 105 | { 106 | return m_paths.count; 107 | } 108 | 109 | 110 | - (void)viewDidLayoutSubviews { 111 | m_table.frame = self.view.bounds; 112 | } 113 | 114 | 115 | @end 116 | -------------------------------------------------------------------------------- /Classes/EPubSettings.h: -------------------------------------------------------------------------------- 1 | // 2 | // EPubSettings.h 3 | // SDKLauncher-iOS 4 | // 5 | // Created by Shane Meyer on 7/27/13. 6 | // Copyright (c) 2014 Readium Foundation and/or its licensees. All rights reserved. 7 | // 8 | // Redistribution and use in source and binary forms, with or without modification, 9 | // are permitted provided that the following conditions are met: 10 | // 1. Redistributions of source code must retain the above copyright notice, this 11 | // list of conditions and the following disclaimer. 12 | // 2. Redistributions in binary form must reproduce the above copyright notice, 13 | // this list of conditions and the following disclaimer in the documentation and/or 14 | // other materials provided with the distribution. 15 | // 3. Neither the name of the organization nor the names of its contributors may be 16 | // used to endorse or promote products derived from this software without specific 17 | // prior written permission. 18 | // 19 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 20 | // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 | // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 22 | // IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 23 | // INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 24 | // BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 26 | // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 27 | // OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 28 | // OF THE POSSIBILITY OF SUCH DAMAGE. 29 | 30 | #import 31 | 32 | extern NSString * const kSDKLauncherEPubSettingsDidChange; 33 | 34 | typedef enum { 35 | EPubSettingsScrollAuto, 36 | EPubSettingsScrollContinuous, 37 | EPubSettingsScrollDoc, 38 | } EPubSettingsScroll; 39 | 40 | typedef enum { 41 | EPubSettingsSyntheticSpreadAuto, 42 | EPubSettingsSyntheticSpreadDouble, 43 | EPubSettingsSyntheticSpreadSingle, 44 | } EPubSettingsSyntheticSpread; 45 | 46 | @interface EPubSettings : NSObject 47 | 48 | @property (nonatomic, assign) CGFloat columnGap; 49 | @property (nonatomic, readonly) NSDictionary *dictionary; 50 | @property (nonatomic, assign) CGFloat fontScale; 51 | @property (nonatomic, assign) EPubSettingsScroll scroll; 52 | @property (nonatomic, assign) EPubSettingsSyntheticSpread syntheticSpread; 53 | 54 | + (EPubSettings *)shared; 55 | 56 | @end 57 | -------------------------------------------------------------------------------- /Classes/EPubSettings.m: -------------------------------------------------------------------------------- 1 | // 2 | // EPubSettings.m 3 | // SDKLauncher-iOS 4 | // 5 | // Created by Shane Meyer on 7/27/13. 6 | // Copyright (c) 2014 Readium Foundation and/or its licensees. All rights reserved. 7 | // 8 | // Redistribution and use in source and binary forms, with or without modification, 9 | // are permitted provided that the following conditions are met: 10 | // 1. Redistributions of source code must retain the above copyright notice, this 11 | // list of conditions and the following disclaimer. 12 | // 2. Redistributions in binary form must reproduce the above copyright notice, 13 | // this list of conditions and the following disclaimer in the documentation and/or 14 | // other materials provided with the distribution. 15 | // 3. Neither the name of the organization nor the names of its contributors may be 16 | // used to endorse or promote products derived from this software without specific 17 | // prior written permission. 18 | // 19 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 20 | // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 | // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 22 | // IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 23 | // INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 24 | // BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 26 | // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 27 | // OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 28 | // OF THE POSSIBILITY OF SUCH DAMAGE. 29 | 30 | #import "EPubSettings.h" 31 | #import "Settings.h" 32 | 33 | 34 | #define kKeyColumnGap @"columnGap" 35 | #define kKeyFontScale @"fontSize" 36 | #define kKeyScroll @"scroll" 37 | #define kKeySyntheticSpread @"syntheticSpread" 38 | 39 | 40 | NSString * const kSDKLauncherEPubSettingsDidChange = @"SDKLauncherEPubSettingsDidChange"; 41 | 42 | 43 | @interface EPubSettings () 44 | 45 | - (void)postNotification; 46 | 47 | @end 48 | 49 | 50 | @implementation EPubSettings 51 | 52 | 53 | - (CGFloat)columnGap { 54 | return [Settings shared].columnGap; 55 | } 56 | 57 | 58 | - (NSDictionary *)dictionary { 59 | EPubSettingsScroll scroll = [Settings shared].scroll; 60 | EPubSettingsSyntheticSpread syntheticSpread = [Settings shared].syntheticSpread; 61 | 62 | return @{ 63 | kKeyColumnGap : [NSNumber numberWithInt:round(self.columnGap)], 64 | kKeyFontScale : [NSNumber numberWithInt:round(100.0 * self.fontScale)], 65 | kKeyScroll : 66 | scroll == EPubSettingsScrollContinuous ? @"scroll-continuous" : 67 | scroll == EPubSettingsScrollDoc ? @"scroll-doc" : @"auto", 68 | kKeySyntheticSpread : 69 | syntheticSpread == EPubSettingsSyntheticSpreadDouble ? @"double" : 70 | syntheticSpread == EPubSettingsSyntheticSpreadSingle ? @"single" : @"auto", 71 | }; 72 | } 73 | 74 | 75 | - (CGFloat)fontScale { 76 | return [Settings shared].fontScale; 77 | } 78 | 79 | 80 | - (void)postNotification { 81 | [[NSNotificationCenter defaultCenter] postNotificationName: 82 | kSDKLauncherEPubSettingsDidChange object:self]; 83 | } 84 | 85 | 86 | - (EPubSettingsScroll)scroll { 87 | return [Settings shared].scroll; 88 | } 89 | 90 | 91 | - (void)setColumnGap:(CGFloat)columnGap { 92 | if ([Settings shared].columnGap != columnGap) { 93 | [Settings shared].columnGap = columnGap; 94 | [self postNotification]; 95 | } 96 | } 97 | 98 | 99 | - (void)setFontScale:(CGFloat)fontScale { 100 | if ([Settings shared].fontScale != fontScale) { 101 | [Settings shared].fontScale = fontScale; 102 | [self postNotification]; 103 | } 104 | } 105 | 106 | 107 | - (void)setScroll:(EPubSettingsScroll)scroll { 108 | if ([Settings shared].scroll != scroll) { 109 | [Settings shared].scroll = scroll; 110 | [self postNotification]; 111 | } 112 | } 113 | 114 | 115 | - (void)setSyntheticSpread:(EPubSettingsSyntheticSpread)syntheticSpread { 116 | if ([Settings shared].syntheticSpread != syntheticSpread) { 117 | [Settings shared].syntheticSpread = syntheticSpread; 118 | [self postNotification]; 119 | } 120 | } 121 | 122 | 123 | + (EPubSettings *)shared { 124 | static EPubSettings *shared = nil; 125 | 126 | if (shared == nil) { 127 | shared = [[self alloc] init]; 128 | } 129 | 130 | return shared; 131 | } 132 | 133 | 134 | - (EPubSettingsSyntheticSpread)syntheticSpread { 135 | return [Settings shared].syntheticSpread; 136 | } 137 | 138 | 139 | @end 140 | -------------------------------------------------------------------------------- /Classes/EPubSettingsController.h: -------------------------------------------------------------------------------- 1 | // 2 | // EPubSettingsController.h 3 | // SDKLauncher-iOS 4 | // 5 | // Created by Shane Meyer on 7/27/13. 6 | // Copyright (c) 2014 Readium Foundation and/or its licensees. All rights reserved. 7 | // 8 | // Redistribution and use in source and binary forms, with or without modification, 9 | // are permitted provided that the following conditions are met: 10 | // 1. Redistributions of source code must retain the above copyright notice, this 11 | // list of conditions and the following disclaimer. 12 | // 2. Redistributions in binary form must reproduce the above copyright notice, 13 | // this list of conditions and the following disclaimer in the documentation and/or 14 | // other materials provided with the distribution. 15 | // 3. Neither the name of the organization nor the names of its contributors may be 16 | // used to endorse or promote products derived from this software without specific 17 | // prior written permission. 18 | // 19 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 20 | // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 | // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 22 | // IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 23 | // INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 24 | // BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 26 | // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 27 | // OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 28 | // OF THE POSSIBILITY OF SUCH DAMAGE. 29 | 30 | #import "BaseViewController.h" 31 | 32 | @interface EPubSettingsController : BaseViewController 33 | 34 | @end 35 | -------------------------------------------------------------------------------- /Classes/EPubSettingsController.m: -------------------------------------------------------------------------------- 1 | // 2 | // EPubSettingsController.m 3 | // SDKLauncher-iOS 4 | // 5 | // Created by Shane Meyer on 7/27/13. 6 | // Copyright (c) 2014 Readium Foundation and/or its licensees. All rights reserved. 7 | // 8 | // Redistribution and use in source and binary forms, with or without modification, 9 | // are permitted provided that the following conditions are met: 10 | // 1. Redistributions of source code must retain the above copyright notice, this 11 | // list of conditions and the following disclaimer. 12 | // 2. Redistributions in binary form must reproduce the above copyright notice, 13 | // this list of conditions and the following disclaimer in the documentation and/or 14 | // other materials provided with the distribution. 15 | // 3. Neither the name of the organization nor the names of its contributors may be 16 | // used to endorse or promote products derived from this software without specific 17 | // prior written permission. 18 | // 19 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 20 | // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 | // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 22 | // IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 23 | // INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 24 | // BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 26 | // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 27 | // OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 28 | // OF THE POSSIBILITY OF SUCH DAMAGE. 29 | 30 | #import "EPubSettingsController.h" 31 | #import "EPubSettings.h" 32 | 33 | 34 | @interface EPubSettingsController () < 35 | UITableViewDataSource, 36 | UITableViewDelegate> 37 | { 38 | @private UITableViewCell *m_cellColumnGap; 39 | @private UITableViewCell *m_cellFontScale; 40 | @private UITableViewCell *m_cellScroll; 41 | @private UITableViewCell *m_cellScrollAuto; 42 | @private UITableViewCell *m_cellScrollContinuous; 43 | @private UITableViewCell *m_cellScrollDoc; 44 | @private UITableViewCell *m_cellSyntheticSpread; 45 | @private UITableViewCell *m_cellSyntheticSpreadAuto; 46 | @private UITableViewCell *m_cellSyntheticSpreadDouble; 47 | @private UITableViewCell *m_cellSyntheticSpreadSingle; 48 | @private NSArray *m_cells; 49 | @private __weak UITableView *m_table; 50 | } 51 | 52 | - (void)updateCells; 53 | 54 | @end 55 | 56 | 57 | @implementation EPubSettingsController 58 | 59 | 60 | - (void)dealloc { 61 | [[NSNotificationCenter defaultCenter] removeObserver:self]; 62 | } 63 | 64 | 65 | - (id)init { 66 | if (self = [super initWithTitle:LocStr(@"EPUB_SETTINGS_TITLE") navBarHidden:NO]) { 67 | if (!IS_IPAD) { 68 | self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] 69 | initWithBarButtonSystemItem:UIBarButtonSystemItemDone 70 | target:self 71 | action:@selector(onTapDone)]; 72 | } 73 | 74 | // Column gap 75 | 76 | int maxValue = MIN(SCREEN_SIZE.width, SCREEN_SIZE.height) / 3.0; 77 | int stepValue = 5; 78 | 79 | while (maxValue % stepValue != 0) { 80 | maxValue--; 81 | } 82 | 83 | UIStepper *stepper = [[UIStepper alloc] init]; 84 | stepper.minimumValue = 0; 85 | stepper.maximumValue = maxValue; 86 | stepper.stepValue = stepValue; 87 | stepper.value = [EPubSettings shared].columnGap; 88 | [stepper addTarget:self action:@selector(onColumnGapDidChange:) 89 | forControlEvents:UIControlEventValueChanged]; 90 | 91 | m_cellColumnGap = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault 92 | reuseIdentifier:nil]; 93 | m_cellColumnGap.accessoryView = stepper; 94 | m_cellColumnGap.selectionStyle = UITableViewCellSelectionStyleNone; 95 | 96 | // Font scale 97 | 98 | stepper = [[UIStepper alloc] init]; 99 | stepper.minimumValue = 0.2; 100 | stepper.maximumValue = 5; 101 | stepper.stepValue = 0.1; 102 | stepper.value = [EPubSettings shared].fontScale; 103 | [stepper addTarget:self action:@selector(onFontScaleDidChange:) 104 | forControlEvents:UIControlEventValueChanged]; 105 | 106 | m_cellFontScale = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault 107 | reuseIdentifier:nil]; 108 | m_cellFontScale.accessoryView = stepper; 109 | m_cellFontScale.selectionStyle = UITableViewCellSelectionStyleNone; 110 | 111 | // Scroll 112 | 113 | m_cellScroll = [[UITableViewCell alloc] initWithStyle: 114 | UITableViewCellStyleDefault reuseIdentifier:nil]; 115 | m_cellScroll.selectionStyle = UITableViewCellSelectionStyleNone; 116 | m_cellScroll.textLabel.text = LocStr(@"EPUB_SETTINGS_SCROLL"); 117 | 118 | m_cellScrollAuto = [[UITableViewCell alloc] initWithStyle: 119 | UITableViewCellStyleDefault reuseIdentifier:nil]; 120 | m_cellScrollAuto.indentationLevel = 1; 121 | m_cellScrollAuto.textLabel.text = LocStr(@"EPUB_SETTINGS_SCROLL_AUTO"); 122 | 123 | m_cellScrollContinuous = [[UITableViewCell alloc] initWithStyle: 124 | UITableViewCellStyleDefault reuseIdentifier:nil]; 125 | m_cellScrollContinuous.indentationLevel = 1; 126 | m_cellScrollContinuous.textLabel.text = LocStr(@"EPUB_SETTINGS_SCROLL_CONTINUOUS"); 127 | 128 | m_cellScrollDoc = [[UITableViewCell alloc] initWithStyle: 129 | UITableViewCellStyleDefault reuseIdentifier:nil]; 130 | m_cellScrollDoc.indentationLevel = 1; 131 | m_cellScrollDoc.textLabel.text = LocStr(@"EPUB_SETTINGS_SCROLL_DOC"); 132 | 133 | // Synthetic spread 134 | 135 | m_cellSyntheticSpread = [[UITableViewCell alloc] initWithStyle: 136 | UITableViewCellStyleDefault reuseIdentifier:nil]; 137 | m_cellSyntheticSpread.selectionStyle = UITableViewCellSelectionStyleNone; 138 | m_cellSyntheticSpread.textLabel.text = LocStr(@"EPUB_SETTINGS_SYNTHETIC_SPREAD"); 139 | 140 | m_cellSyntheticSpreadAuto = [[UITableViewCell alloc] initWithStyle: 141 | UITableViewCellStyleDefault reuseIdentifier:nil]; 142 | m_cellSyntheticSpreadAuto.indentationLevel = 1; 143 | m_cellSyntheticSpreadAuto.textLabel.text = LocStr(@"EPUB_SETTINGS_SYNTHETIC_SPREAD_AUTO"); 144 | 145 | m_cellSyntheticSpreadDouble = [[UITableViewCell alloc] initWithStyle: 146 | UITableViewCellStyleDefault reuseIdentifier:nil]; 147 | m_cellSyntheticSpreadDouble.indentationLevel = 1; 148 | m_cellSyntheticSpreadDouble.textLabel.text = LocStr(@"EPUB_SETTINGS_SYNTHETIC_SPREAD_DOUBLE"); 149 | 150 | m_cellSyntheticSpreadSingle = [[UITableViewCell alloc] initWithStyle: 151 | UITableViewCellStyleDefault reuseIdentifier:nil]; 152 | m_cellSyntheticSpreadSingle.indentationLevel = 1; 153 | m_cellSyntheticSpreadSingle.textLabel.text = LocStr(@"EPUB_SETTINGS_SYNTHETIC_SPREAD_SINGLE"); 154 | 155 | // Finish up 156 | 157 | m_cells = @[ 158 | m_cellScroll, 159 | m_cellScrollAuto, 160 | m_cellScrollDoc, 161 | m_cellScrollContinuous, 162 | m_cellSyntheticSpread, 163 | m_cellSyntheticSpreadAuto, 164 | m_cellSyntheticSpreadSingle, 165 | m_cellSyntheticSpreadDouble, 166 | m_cellFontScale, 167 | m_cellColumnGap 168 | ]; 169 | 170 | [self updateCells]; 171 | 172 | self.contentSizeForViewInPopover = CGSizeMake(320, 44 * m_cells.count); 173 | 174 | [[NSNotificationCenter defaultCenter] 175 | addObserver:self 176 | selector:@selector(updateCells) 177 | name:kSDKLauncherEPubSettingsDidChange 178 | object:nil]; 179 | } 180 | 181 | return self; 182 | } 183 | 184 | 185 | - (void)loadView { 186 | self.view = [[UIView alloc] init]; 187 | 188 | UITableView *table = [[UITableView alloc] initWithFrame:CGRectZero style:UITableViewStylePlain]; 189 | m_table = table; 190 | table.dataSource = self; 191 | table.delegate = self; 192 | [self.view addSubview:table]; 193 | } 194 | 195 | 196 | - (void)onColumnGapDidChange:(UIStepper *)stepper { 197 | [EPubSettings shared].columnGap = stepper.value; 198 | } 199 | 200 | 201 | - (void)onFontScaleDidChange:(UIStepper *)stepper { 202 | [EPubSettings shared].fontScale = stepper.value; 203 | } 204 | 205 | 206 | - (void)onTapDone { 207 | [self dismissViewControllerAnimated:YES completion:nil]; 208 | } 209 | 210 | 211 | - (UITableViewCell *) 212 | tableView:(UITableView *)tableView 213 | cellForRowAtIndexPath:(NSIndexPath *)indexPath 214 | { 215 | return [m_cells objectAtIndex:indexPath.row]; 216 | } 217 | 218 | 219 | - (void) 220 | tableView:(UITableView *)tableView 221 | didSelectRowAtIndexPath:(NSIndexPath *)indexPath 222 | { 223 | [tableView deselectRowAtIndexPath:indexPath animated:YES]; 224 | UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath]; 225 | 226 | if (cell == m_cellScrollAuto) { 227 | [EPubSettings shared].scroll = EPubSettingsScrollAuto; 228 | } 229 | else if (cell == m_cellScrollContinuous) { 230 | [EPubSettings shared].scroll = EPubSettingsScrollContinuous; 231 | } 232 | else if (cell == m_cellScrollDoc) { 233 | [EPubSettings shared].scroll = EPubSettingsScrollDoc; 234 | } 235 | else if (cell == m_cellSyntheticSpreadAuto) { 236 | [EPubSettings shared].syntheticSpread = EPubSettingsSyntheticSpreadAuto; 237 | } 238 | else if (cell == m_cellSyntheticSpreadDouble) { 239 | [EPubSettings shared].syntheticSpread = EPubSettingsSyntheticSpreadDouble; 240 | } 241 | else if (cell == m_cellSyntheticSpreadSingle) { 242 | [EPubSettings shared].syntheticSpread = EPubSettingsSyntheticSpreadSingle; 243 | } 244 | } 245 | 246 | 247 | - (NSInteger) 248 | tableView:(UITableView *)tableView 249 | numberOfRowsInSection:(NSInteger)section 250 | { 251 | return m_cells.count; 252 | } 253 | 254 | 255 | - (void)updateCells { 256 | EPubSettings *settings = [EPubSettings shared]; 257 | 258 | m_cellColumnGap.textLabel.text = LocStr(@"EPUB_SETTINGS_COLUMN_GAP", 259 | (int)round(settings.columnGap)); 260 | 261 | m_cellFontScale.textLabel.text = LocStr(@"EPUB_SETTINGS_FONT_SCALE", 262 | (int)round(100.0 * settings.fontScale)); 263 | 264 | m_cellScrollAuto.accessoryType = 265 | (settings.scroll == EPubSettingsScrollAuto) ? 266 | UITableViewCellAccessoryCheckmark : UITableViewCellAccessoryNone; 267 | 268 | m_cellScrollContinuous.accessoryType = 269 | (settings.scroll == EPubSettingsScrollContinuous) ? 270 | UITableViewCellAccessoryCheckmark : UITableViewCellAccessoryNone; 271 | 272 | m_cellScrollDoc.accessoryType = 273 | (settings.scroll == EPubSettingsScrollDoc) ? 274 | UITableViewCellAccessoryCheckmark : UITableViewCellAccessoryNone; 275 | 276 | m_cellSyntheticSpreadAuto.accessoryType = 277 | (settings.syntheticSpread == EPubSettingsSyntheticSpreadAuto) ? 278 | UITableViewCellAccessoryCheckmark : UITableViewCellAccessoryNone; 279 | 280 | m_cellSyntheticSpreadDouble.accessoryType = 281 | (settings.syntheticSpread == EPubSettingsSyntheticSpreadDouble) ? 282 | UITableViewCellAccessoryCheckmark : UITableViewCellAccessoryNone; 283 | 284 | m_cellSyntheticSpreadSingle.accessoryType = 285 | (settings.syntheticSpread == EPubSettingsSyntheticSpreadSingle) ? 286 | UITableViewCellAccessoryCheckmark : UITableViewCellAccessoryNone; 287 | } 288 | 289 | 290 | - (void)viewDidLayoutSubviews { 291 | m_table.frame = self.view.bounds; 292 | } 293 | 294 | 295 | @end 296 | -------------------------------------------------------------------------------- /Classes/EPubViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // EPubViewController.h 3 | // SDKLauncher-iOS 4 | // 5 | // Created by Shane Meyer on 6/5/13. 6 | // Copyright (c) 2014 Readium Foundation and/or its licensees. All rights reserved. 7 | // 8 | // Redistribution and use in source and binary forms, with or without modification, 9 | // are permitted provided that the following conditions are met: 10 | // 1. Redistributions of source code must retain the above copyright notice, this 11 | // list of conditions and the following disclaimer. 12 | // 2. Redistributions in binary form must reproduce the above copyright notice, 13 | // this list of conditions and the following disclaimer in the documentation and/or 14 | // other materials provided with the distribution. 15 | // 3. Neither the name of the organization nor the names of its contributors may be 16 | // used to endorse or promote products derived from this software without specific 17 | // prior written permission. 18 | // 19 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 20 | // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 | // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 22 | // IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 23 | // INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 24 | // BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 26 | // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 27 | // OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 28 | // OF THE POSSIBILITY OF SUCH DAMAGE. 29 | 30 | #import "BaseViewController.h" 31 | 32 | @class Bookmark; 33 | @class RDContainer; 34 | @class RDNavigationElement; 35 | @class RDPackage; 36 | @class RDSpineItem; 37 | 38 | @interface EPubViewController : BaseViewController 39 | 40 | - (instancetype) 41 | initWithContainer:(RDContainer *)container 42 | package:(RDPackage *)package; 43 | 44 | - (instancetype) 45 | initWithContainer:(RDContainer *)container 46 | package:(RDPackage *)package 47 | bookmark:(Bookmark *)bookmark; 48 | 49 | - (instancetype) 50 | initWithContainer:(RDContainer *)container 51 | package:(RDPackage *)package 52 | navElement:(RDNavigationElement *)navElement; 53 | 54 | - (instancetype) 55 | initWithContainer:(RDContainer *)container 56 | package:(RDPackage *)package 57 | spineItem:(RDSpineItem *)spineItem 58 | cfi:(NSString *)cfi; 59 | 60 | @end 61 | -------------------------------------------------------------------------------- /Classes/EPubViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // EPubViewController.m 3 | // SDKLauncher-iOS 4 | // 5 | // Created by Shane Meyer on 6/5/13. 6 | // Copyright (c) 2014 Readium Foundation and/or its licensees. All rights reserved. 7 | // 8 | // Redistribution and use in source and binary forms, with or without modification, 9 | // are permitted provided that the following conditions are met: 10 | // 1. Redistributions of source code must retain the above copyright notice, this 11 | // list of conditions and the following disclaimer. 12 | // 2. Redistributions in binary form must reproduce the above copyright notice, 13 | // this list of conditions and the following disclaimer in the documentation and/or 14 | // other materials provided with the distribution. 15 | // 3. Neither the name of the organization nor the names of its contributors may be 16 | // used to endorse or promote products derived from this software without specific 17 | // prior written permission. 18 | // 19 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 20 | // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 | // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 22 | // IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 23 | // INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 24 | // BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 26 | // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 27 | // OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 28 | // OF THE POSSIBILITY OF SUCH DAMAGE. 29 | 30 | #import "EPubViewController.h" 31 | #import "Bookmark.h" 32 | #import "BookmarkDatabase.h" 33 | #import "EPubSettings.h" 34 | #import "EPubSettingsController.h" 35 | #import "RDContainer.h" 36 | #import "RDNavigationElement.h" 37 | #import "RDPackage.h" 38 | #import "RDPackageResourceServer.h" 39 | #import "RDSpineItem.h" 40 | #import 41 | 42 | 43 | @interface EPubViewController () < 44 | RDPackageResourceServerDelegate, 45 | UIAlertViewDelegate, 46 | UIPopoverControllerDelegate, 47 | UIWebViewDelegate, 48 | WKScriptMessageHandler> 49 | { 50 | @private UIAlertView *m_alertAddBookmark; 51 | @private RDContainer *m_container; 52 | @private BOOL m_currentPageCanGoLeft; 53 | @private BOOL m_currentPageCanGoRight; 54 | @private BOOL m_currentPageIsFixedLayout; 55 | @private NSArray* m_currentPageOpenPagesArray; 56 | @private BOOL m_currentPageProgressionIsLTR; 57 | @private int m_currentPageSpineItemCount; 58 | @private NSString *m_initialCFI; 59 | @private BOOL m_moIsPlaying; 60 | @private RDNavigationElement *m_navElement; 61 | @private RDPackage *m_package; 62 | @private UIPopoverController *m_popover; 63 | @private RDPackageResourceServer *m_resourceServer; 64 | @private RDSpineItem *m_spineItem; 65 | @private __weak UIWebView *m_webViewUI; 66 | @private __weak WKWebView *m_webViewWK; 67 | } 68 | 69 | @end 70 | 71 | 72 | @implementation EPubViewController 73 | 74 | 75 | - (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex { 76 | m_alertAddBookmark = nil; 77 | 78 | if (buttonIndex == 1) { 79 | UITextField *textField = [alertView textFieldAtIndex:0]; 80 | 81 | NSString *title = [textField.text stringByTrimmingCharactersInSet: 82 | [NSCharacterSet whitespaceAndNewlineCharacterSet]]; 83 | 84 | [self executeJavaScript:@"ReadiumSDK.reader.bookmarkCurrentPage()" 85 | completionHandler:^(id response, NSError *error) 86 | { 87 | NSString *s = response; 88 | 89 | if (error != nil || s == nil || ![s isKindOfClass:[NSString class]] || s.length == 0) { 90 | return; 91 | } 92 | 93 | NSData *data = [s dataUsingEncoding:NSUTF8StringEncoding]; 94 | 95 | NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:data 96 | options:0 error:&error]; 97 | 98 | Bookmark *bookmark = [[Bookmark alloc] 99 | initWithCFI:[dict objectForKey:@"contentCFI"] 100 | containerPath:m_container.path 101 | idref:[dict objectForKey:@"idref"] 102 | title:title]; 103 | 104 | if (bookmark == nil) { 105 | NSLog(@"The bookmark is nil!"); 106 | } 107 | else { 108 | [[BookmarkDatabase shared] addBookmark:bookmark]; 109 | } 110 | }]; 111 | } 112 | } 113 | 114 | 115 | - (void)cleanUp { 116 | if (m_webViewWK != nil) { 117 | [m_webViewWK.configuration.userContentController removeScriptMessageHandlerForName:@"readium"]; 118 | } 119 | 120 | [[NSNotificationCenter defaultCenter] removeObserver:self]; 121 | m_moIsPlaying = NO; 122 | 123 | if (m_alertAddBookmark != nil) { 124 | m_alertAddBookmark.delegate = nil; 125 | [m_alertAddBookmark dismissWithClickedButtonIndex:999 animated:NO]; 126 | m_alertAddBookmark = nil; 127 | } 128 | 129 | if (m_popover != nil) { 130 | [m_popover dismissPopoverAnimated:NO]; 131 | m_popover = nil; 132 | } 133 | } 134 | 135 | 136 | - (BOOL)commonInit { 137 | 138 | // Load the special payloads. This is optional (the payloads can be nil), in which case 139 | // MathJax and annotations.css functionality will be disabled. 140 | 141 | NSBundle *bundle = [NSBundle mainBundle]; 142 | NSString *path = [bundle pathForResource:@"annotations" ofType:@"css"]; 143 | NSData *payloadAnnotations = (path == nil) ? nil : [[NSData alloc] initWithContentsOfFile:path]; 144 | path = [bundle pathForResource:@"MathJax" ofType:@"js" inDirectory:@"mathjax"]; 145 | NSData *payloadMathJax = (path == nil) ? nil : [[NSData alloc] initWithContentsOfFile:path]; 146 | 147 | m_resourceServer = [[RDPackageResourceServer alloc] 148 | initWithDelegate:self 149 | package:m_package 150 | specialPayloadAnnotationsCSS:payloadAnnotations 151 | specialPayloadMathJaxJS:payloadMathJax]; 152 | 153 | if (m_resourceServer == nil) { 154 | return NO; 155 | } 156 | 157 | // Configure the package's root URL. Rather than "localhost", "127.0.0.1" is specified in the 158 | // following URL to work around an issue introduced in iOS 7.0. When an iOS 7 device is offline 159 | // (Wi-Fi off, or airplane mode on), audio and video fails to be served by UIWebView / QuickTime, 160 | // even though being offline is irrelevant for an embedded HTTP server. Daniel suggested trying 161 | // 127.0.0.1 in case the underlying issue was host name resolution, and it works. 162 | 163 | m_package.rootURL = [NSString stringWithFormat:@"http://127.0.0.1:%d/", m_resourceServer.port]; 164 | 165 | // Observe application background/foreground notifications 166 | // HTTP server becomes unreachable after the application has become inactive 167 | // so we need to stop and restart it whenever it happens 168 | [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleAppWillResignActiveNotification:) name:UIApplicationWillResignActiveNotification object:nil]; 169 | [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleAppWillEnterForegroundNotification:) name:UIApplicationWillEnterForegroundNotification object:nil]; 170 | 171 | [self updateNavigationItems]; 172 | return YES; 173 | } 174 | 175 | 176 | - (void) 177 | executeJavaScript:(NSString *)javaScript 178 | completionHandler:(void (^)(id response, NSError *error))completionHandler 179 | { 180 | if (m_webViewUI != nil) { 181 | NSString *response = [m_webViewUI stringByEvaluatingJavaScriptFromString:javaScript]; 182 | if (completionHandler != nil) { 183 | completionHandler(response, nil); 184 | } 185 | } 186 | else if (m_webViewWK != nil) { 187 | [m_webViewWK evaluateJavaScript:javaScript completionHandler:^(id response, NSError *error) { 188 | if (error != nil) { 189 | NSLog(@"%@", error); 190 | } 191 | if (completionHandler != nil) { 192 | if ([NSThread isMainThread]) { 193 | completionHandler(response, error); 194 | } 195 | else { 196 | dispatch_async(dispatch_get_main_queue(), ^{ 197 | completionHandler(response, error); 198 | }); 199 | } 200 | } 201 | }]; 202 | } 203 | else if (completionHandler != nil) { 204 | completionHandler(nil, nil); 205 | } 206 | } 207 | 208 | 209 | - (void)handleMediaOverlayStatusDidChange:(NSString *)payload { 210 | NSData *data = [payload dataUsingEncoding:NSUTF8StringEncoding]; 211 | NSError *error = nil; 212 | NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error]; 213 | 214 | if (error != nil || dict == nil || ![dict isKindOfClass:[NSDictionary class]]) { 215 | NSLog(@"The mediaOverlayStatusDidChange payload is invalid! (%@, %@)", error, dict); 216 | } 217 | else { 218 | NSNumber *n = dict[@"isPlaying"]; 219 | 220 | if (n != nil && [n isKindOfClass:[NSNumber class]]) { 221 | m_moIsPlaying = n.boolValue; 222 | [self updateToolbar]; 223 | } 224 | } 225 | } 226 | 227 | 228 | - (void)handlePageDidChange:(NSString *)payload { 229 | NSData *data = [payload dataUsingEncoding:NSUTF8StringEncoding]; 230 | NSError *error = nil; 231 | NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error]; 232 | 233 | if (error != nil || dict == nil || ![dict isKindOfClass:[NSDictionary class]]) { 234 | NSLog(@"The pageDidChange payload is invalid! (%@, %@)", error, dict); 235 | } 236 | else { 237 | NSNumber *n = dict[@"canGoLeft_"]; 238 | m_currentPageCanGoLeft = [n isKindOfClass:[NSNumber class]] && n.boolValue; 239 | 240 | n = dict[@"canGoRight_"]; 241 | m_currentPageCanGoRight = [n isKindOfClass:[NSNumber class]] && n.boolValue; 242 | 243 | n = dict[@"isRightToLeft"]; 244 | m_currentPageProgressionIsLTR = [n isKindOfClass:[NSNumber class]] && !n.boolValue; 245 | 246 | n = dict[@"isFixedLayout"]; 247 | m_currentPageIsFixedLayout = [n isKindOfClass:[NSNumber class]] && n.boolValue; 248 | 249 | n = dict[@"spineItemCount"]; 250 | m_currentPageSpineItemCount = [n isKindOfClass:[NSNumber class]] ? n.intValue : 0; 251 | 252 | NSArray *array = dict[@"openPages"]; 253 | m_currentPageOpenPagesArray = [array isKindOfClass:[NSArray class]] ? array : nil; 254 | 255 | if (m_webViewUI != nil) { 256 | m_webViewUI.hidden = NO; 257 | } 258 | else if (m_webViewWK != nil) { 259 | m_webViewWK.hidden = NO; 260 | } 261 | 262 | [self updateToolbar]; 263 | } 264 | } 265 | 266 | 267 | - (void)handleReaderDidInitialize { 268 | NSMutableDictionary *dict = [NSMutableDictionary dictionary]; 269 | dict[@"package"] = m_package.dictionary; 270 | dict[@"settings"] = [EPubSettings shared].dictionary; 271 | 272 | NSDictionary *pageDict = nil; 273 | 274 | if (m_spineItem == nil) { 275 | } 276 | else if (m_initialCFI != nil && m_initialCFI.length > 0) { 277 | pageDict = @{ 278 | @"idref" : m_spineItem.idref, 279 | @"elementCfi" : m_initialCFI 280 | }; 281 | } 282 | else if (m_navElement.content != nil && m_navElement.content.length > 0) { 283 | pageDict = @{ 284 | @"contentRefUrl" : m_navElement.content, 285 | @"sourceFileHref" : (m_navElement.sourceHref == nil ? 286 | @"" : m_navElement.sourceHref) 287 | }; 288 | } 289 | else { 290 | pageDict = @{ 291 | @"idref" : m_spineItem.idref 292 | }; 293 | } 294 | 295 | if (pageDict != nil) { 296 | dict[@"openPageRequest"] = pageDict; 297 | } 298 | 299 | NSData *data = [NSJSONSerialization dataWithJSONObject:dict options:0 error:nil]; 300 | 301 | if (data != nil) { 302 | NSString *arg = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; 303 | arg = [NSString stringWithFormat:@"ReadiumSDK.reader.openBook(%@)", arg]; 304 | [self executeJavaScript:arg completionHandler:nil]; 305 | } 306 | } 307 | 308 | 309 | - (instancetype) 310 | initWithContainer:(RDContainer *)container 311 | package:(RDPackage *)package 312 | { 313 | return [self initWithContainer:container package:package spineItem:nil cfi:nil]; 314 | } 315 | 316 | 317 | - (instancetype) 318 | initWithContainer:(RDContainer *)container 319 | package:(RDPackage *)package 320 | bookmark:(Bookmark *)bookmark 321 | { 322 | RDSpineItem *spineItem = nil; 323 | 324 | for (RDSpineItem *currSpineItem in package.spineItems) { 325 | if ([currSpineItem.idref isEqualToString:bookmark.idref]) { 326 | spineItem = currSpineItem; 327 | break; 328 | } 329 | } 330 | 331 | return [self 332 | initWithContainer:container 333 | package:package 334 | spineItem:spineItem 335 | cfi:bookmark.cfi]; 336 | } 337 | 338 | 339 | - (instancetype) 340 | initWithContainer:(RDContainer *)container 341 | package:(RDPackage *)package 342 | navElement:(RDNavigationElement *)navElement 343 | { 344 | if (container == nil || package == nil) { 345 | return nil; 346 | } 347 | 348 | RDSpineItem *spineItem = nil; 349 | 350 | if (package.spineItems.count > 0) { 351 | spineItem = [package.spineItems objectAtIndex:0]; 352 | } 353 | 354 | if (spineItem == nil) { 355 | return nil; 356 | } 357 | 358 | if (self = [super initWithTitle:package.title navBarHidden:NO]) { 359 | m_container = container; 360 | m_navElement = navElement; 361 | m_package = package; 362 | m_spineItem = spineItem; 363 | 364 | if (![self commonInit]) { 365 | return nil; 366 | } 367 | } 368 | 369 | return self; 370 | } 371 | 372 | 373 | - (instancetype) 374 | initWithContainer:(RDContainer *)container 375 | package:(RDPackage *)package 376 | spineItem:(RDSpineItem *)spineItem 377 | cfi:(NSString *)cfi 378 | { 379 | if (container == nil || package == nil) { 380 | return nil; 381 | } 382 | 383 | if (spineItem == nil && package.spineItems.count > 0) { 384 | spineItem = [package.spineItems objectAtIndex:0]; 385 | } 386 | 387 | if (spineItem == nil) { 388 | return nil; 389 | } 390 | 391 | if (self = [super initWithTitle:package.title navBarHidden:NO]) { 392 | m_container = container; 393 | m_initialCFI = cfi; 394 | m_package = package; 395 | m_spineItem = spineItem; 396 | 397 | if (![self commonInit]) { 398 | return nil; 399 | } 400 | } 401 | 402 | return self; 403 | } 404 | 405 | 406 | - (void)loadView { 407 | self.view = [[UIView alloc] init]; 408 | self.view.backgroundColor = [UIColor whiteColor]; 409 | 410 | // Notifications 411 | 412 | NSNotificationCenter *nc = [NSNotificationCenter defaultCenter]; 413 | 414 | [nc addObserver:self selector:@selector(onEPubSettingsDidChange:) 415 | name:kSDKLauncherEPubSettingsDidChange object:nil]; 416 | 417 | // Create the web view. The choice of web view type is based on the existence of the WKWebView 418 | // class, but this could be decided some other way. 419 | 420 | // The "no optimize" RequireJS option means that the entire "readium-shared-js" folder must be copied in to the OSX app bundle's "scripts" folder! (including "node_modules" subfolder, which is populated when invoking the "npm run prepare" build command) There is therefore some significant filesystem / size overhead, but the benefits are significant too: no need for the WebView to fetch sourcemaps, and to attempt to un-mangle the obfuscated Javascript during debugging. 421 | // However, the recommended development-time pattern is to invoke "npm run build" in order to refresh the "build-output" folder, with the RJS_UGLY environment variable set to "false" or "no". This way, the RequireJS single/multiple bundle(s) will be in readable uncompressed form. 422 | //NSString* readerFileName = @"reader_RequireJS-no-optimize.html"; 423 | 424 | //NSString* readerFileName = @"reader_RequireJS-multiple-bundles.html"; 425 | NSString* readerFileName = @"reader_RequireJS-single-bundle.html"; 426 | 427 | 428 | if ([WKWebView class] != nil) { 429 | WKWebViewConfiguration *config = [[WKWebViewConfiguration alloc] init]; 430 | config.allowsInlineMediaPlayback = YES; 431 | config.mediaPlaybackRequiresUserAction = NO; 432 | 433 | // Configure a "readium" message handler, which is used by host_app_feedback.js. 434 | 435 | WKUserContentController *contentController = [[WKUserContentController alloc] init]; 436 | [contentController addScriptMessageHandler:self name:@"readium"]; 437 | config.userContentController = contentController; 438 | 439 | WKWebView *webView = [[WKWebView alloc] initWithFrame:CGRectZero configuration:config]; 440 | m_webViewWK = webView; 441 | webView.hidden = YES; 442 | webView.scrollView.bounces = NO; 443 | [self.view addSubview:webView]; 444 | 445 | // RDPackageResourceConnection looks at corePaths and corePrefixes in the following 446 | // query string to determine what core resources it should provide responses for. Since 447 | // WKWebView can't handle file URLs, the web server must provide these resources. 448 | 449 | NSString *url = [NSString stringWithFormat: 450 | @"%@%@?" 451 | @"corePaths=readium-shared-js_all.js,readium-shared-js_all.js.map,epubReadingSystem.js,host_app_feedback.js,sdk.css&" 452 | @"corePrefixes=readium-shared-js", 453 | m_package.rootURL, 454 | readerFileName]; 455 | 456 | [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:url]]]; 457 | } 458 | else { 459 | UIWebView *webView = [[UIWebView alloc] init]; 460 | m_webViewUI = webView; 461 | webView.delegate = self; 462 | webView.hidden = YES; 463 | webView.scalesPageToFit = YES; 464 | webView.scrollView.bounces = NO; 465 | webView.allowsInlineMediaPlayback = YES; 466 | webView.mediaPlaybackRequiresUserAction = NO; 467 | [self.view addSubview:webView]; 468 | 469 | NSURL *url = [[NSBundle mainBundle] URLForResource:readerFileName withExtension:nil]; 470 | [webView loadRequest:[NSURLRequest requestWithURL:url]]; 471 | } 472 | } 473 | 474 | - (void)onClickAddBookmark { 475 | if (m_alertAddBookmark == nil) { 476 | m_alertAddBookmark = [[UIAlertView alloc] 477 | initWithTitle:LocStr(@"ADD_BOOKMARK_PROMPT_TITLE") 478 | message:nil 479 | delegate:self 480 | cancelButtonTitle:LocStr(@"GENERIC_CANCEL") 481 | otherButtonTitles:LocStr(@"GENERIC_OK"), nil]; 482 | m_alertAddBookmark.alertViewStyle = UIAlertViewStylePlainTextInput; 483 | UITextField *textField = [m_alertAddBookmark textFieldAtIndex:0]; 484 | textField.placeholder = LocStr(@"ADD_BOOKMARK_PROMPT_PLACEHOLDER"); 485 | [m_alertAddBookmark show]; 486 | } 487 | } 488 | 489 | 490 | - (void)onClickMONext { 491 | [self executeJavaScript:@"ReadiumSDK.reader.nextMediaOverlay()" completionHandler:nil]; 492 | } 493 | 494 | 495 | - (void)onClickMOPause { 496 | [self executeJavaScript:@"ReadiumSDK.reader.toggleMediaOverlay()" completionHandler:nil]; 497 | } 498 | 499 | 500 | - (void)onClickMOPlay { 501 | [self executeJavaScript:@"ReadiumSDK.reader.toggleMediaOverlay()" completionHandler:nil]; 502 | } 503 | 504 | 505 | - (void)onClickMOPrev { 506 | [self executeJavaScript:@"ReadiumSDK.reader.previousMediaOverlay()" completionHandler:nil]; 507 | } 508 | 509 | 510 | - (void)onClickNext { 511 | [self executeJavaScript:@"ReadiumSDK.reader.openPageNext()" completionHandler:nil]; 512 | } 513 | 514 | 515 | - (void)onClickPrev { 516 | [self executeJavaScript:@"ReadiumSDK.reader.openPagePrev()" completionHandler:nil]; 517 | } 518 | 519 | 520 | - (void)onClickSettings { 521 | EPubSettingsController *c = [[EPubSettingsController alloc] init]; 522 | UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:c]; 523 | 524 | if (IS_IPAD) { 525 | if (m_popover == nil) { 526 | m_popover = [[UIPopoverController alloc] initWithContentViewController:nav]; 527 | m_popover.delegate = self; 528 | [m_popover presentPopoverFromBarButtonItem:self.navigationItem.rightBarButtonItem 529 | permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES]; 530 | } 531 | } 532 | else { 533 | [self presentViewController:nav animated:YES completion:nil]; 534 | } 535 | } 536 | 537 | 538 | - (void)onEPubSettingsDidChange:(NSNotification *)notification { 539 | [self passSettingsToJavaScript]; 540 | } 541 | 542 | 543 | - (void) 544 | packageResourceServer:(RDPackageResourceServer *)packageResourceServer 545 | executeJavaScript:(NSString *)javaScript 546 | { 547 | if ([NSThread isMainThread]) { 548 | [self executeJavaScript:javaScript completionHandler:nil]; 549 | } 550 | else { 551 | dispatch_async(dispatch_get_main_queue(), ^{ 552 | [self executeJavaScript:javaScript completionHandler:nil]; 553 | }); 554 | } 555 | } 556 | 557 | 558 | - (void)passSettingsToJavaScript { 559 | NSData *data = [NSJSONSerialization dataWithJSONObject:[EPubSettings shared].dictionary 560 | options:0 error:nil]; 561 | 562 | if (data != nil) { 563 | NSString *s = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; 564 | 565 | if (s != nil && s.length > 0) { 566 | s = [NSString stringWithFormat:@"ReadiumSDK.reader.updateSettings(%@)", s]; 567 | [self executeJavaScript:s completionHandler:nil]; 568 | } 569 | } 570 | } 571 | 572 | 573 | - (void)popoverControllerDidDismissPopover:(UIPopoverController *)popoverController { 574 | m_popover = nil; 575 | } 576 | 577 | 578 | - (void)updateNavigationItems { 579 | self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] 580 | initWithBarButtonSystemItem:UIBarButtonSystemItemAction 581 | target:self 582 | action:@selector(onClickSettings)]; 583 | } 584 | 585 | 586 | - (void)updateToolbar { 587 | if ((m_webViewUI != nil && m_webViewUI.hidden) || (m_webViewWK != nil && m_webViewWK.hidden)) { 588 | self.toolbarItems = nil; 589 | return; 590 | } 591 | 592 | NSMutableArray *items = [NSMutableArray arrayWithCapacity:8]; 593 | 594 | UIBarButtonItem *itemFixed = [[UIBarButtonItem alloc] 595 | initWithBarButtonSystemItem:UIBarButtonSystemItemFixedSpace 596 | target:nil 597 | action:nil]; 598 | 599 | itemFixed.width = 12; 600 | 601 | static NSString *arrowL = @"\u2190"; 602 | static NSString *arrowR = @"\u2192"; 603 | 604 | UIBarButtonItem *itemNext = [[UIBarButtonItem alloc] 605 | initWithTitle:m_currentPageProgressionIsLTR ? arrowR : arrowL 606 | style:UIBarButtonItemStylePlain 607 | target:self 608 | action:@selector(onClickNext)]; 609 | 610 | UIBarButtonItem *itemPrev = [[UIBarButtonItem alloc] 611 | initWithTitle:m_currentPageProgressionIsLTR ? arrowL : arrowR 612 | style:UIBarButtonItemStylePlain 613 | target:self 614 | action:@selector(onClickPrev)]; 615 | 616 | if (m_currentPageProgressionIsLTR) { 617 | [items addObject:itemPrev]; 618 | [items addObject:itemFixed]; 619 | [items addObject:itemNext]; 620 | } 621 | else { 622 | [items addObject:itemNext]; 623 | [items addObject:itemFixed]; 624 | [items addObject:itemPrev]; 625 | } 626 | 627 | [items addObject:itemFixed]; 628 | 629 | UILabel *label = [[UILabel alloc] init]; 630 | label.backgroundColor = [UIColor clearColor]; 631 | label.font = [UIFont systemFontOfSize:16]; 632 | label.textColor = [UIColor blackColor]; 633 | 634 | BOOL canGoNext = m_currentPageProgressionIsLTR ? m_currentPageCanGoRight : m_currentPageCanGoLeft; 635 | BOOL canGoPrevious = m_currentPageProgressionIsLTR ? m_currentPageCanGoLeft : m_currentPageCanGoRight; 636 | 637 | itemNext.enabled = canGoNext; 638 | itemPrev.enabled = canGoPrevious; 639 | 640 | if (m_currentPageOpenPagesArray == nil || [m_currentPageOpenPagesArray count] <= 0) { 641 | label.text = @""; 642 | } 643 | else { 644 | 645 | NSMutableArray *pageNumbers = [NSMutableArray array]; 646 | 647 | for (NSDictionary *pageDict in m_currentPageOpenPagesArray) { 648 | 649 | NSNumber *spineItemIndex = [pageDict valueForKey:@"spineItemIndex"]; 650 | NSNumber *spineItemPageIndex = [pageDict valueForKey:@"spineItemPageIndex"]; 651 | 652 | int pageIndex = m_currentPageIsFixedLayout ? spineItemIndex.intValue : spineItemPageIndex.intValue; 653 | 654 | [pageNumbers addObject: [NSNumber numberWithInt:pageIndex + 1]]; 655 | } 656 | 657 | NSString* currentPages = [NSString stringWithFormat:@"%@", [pageNumbers componentsJoinedByString:@"-"]]; 658 | 659 | int pageCount = 0; 660 | if ([m_currentPageOpenPagesArray count] > 0) 661 | { 662 | NSDictionary *firstOpenPageDict = [m_currentPageOpenPagesArray objectAtIndex:0]; 663 | NSNumber *number = [firstOpenPageDict valueForKey:@"spineItemPageCount"]; 664 | 665 | pageCount = m_currentPageIsFixedLayout ? m_currentPageSpineItemCount: number.intValue; 666 | } 667 | NSString* totalPages = [NSString stringWithFormat:@"%d", pageCount]; 668 | 669 | label.text = LocStr(@"PAGE_X_OF_Y", [currentPages UTF8String], [totalPages UTF8String], m_currentPageIsFixedLayout?[@"FXL" UTF8String]:[@"reflow" UTF8String]); 670 | } 671 | 672 | [label sizeToFit]; 673 | 674 | [items addObject:[[UIBarButtonItem alloc] initWithCustomView:label]]; 675 | 676 | [items addObject:[[UIBarButtonItem alloc] 677 | initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace 678 | target:nil 679 | action:nil] 680 | ]; 681 | 682 | [self executeJavaScript:@"ReadiumSDK.reader.isMediaOverlayAvailable()" 683 | completionHandler:^(id response, NSError *error) 684 | { 685 | if (error == nil && response != nil && ( 686 | ([response isKindOfClass:[NSNumber class]] && ((NSNumber *)response).boolValue) 687 | || 688 | ([response isKindOfClass:[NSString class]] && [((NSString *)response) isEqualToString:@"true"]) 689 | )) 690 | { 691 | [items addObject:[[UIBarButtonItem alloc] 692 | initWithTitle:@"<" 693 | style:UIBarButtonItemStylePlain 694 | target:self 695 | action:@selector(onClickMOPrev)] 696 | ]; 697 | 698 | if (m_moIsPlaying) { 699 | [items addObject:[[UIBarButtonItem alloc] 700 | initWithBarButtonSystemItem:UIBarButtonSystemItemPause 701 | target:self 702 | action:@selector(onClickMOPause)] 703 | ]; 704 | } 705 | else { 706 | [items addObject:[[UIBarButtonItem alloc] 707 | initWithBarButtonSystemItem:UIBarButtonSystemItemPlay 708 | target:self 709 | action:@selector(onClickMOPlay)] 710 | ]; 711 | } 712 | 713 | [items addObject:[[UIBarButtonItem alloc] 714 | initWithTitle:@">" 715 | style:UIBarButtonItemStylePlain 716 | target:self 717 | action:@selector(onClickMONext)] 718 | ]; 719 | 720 | [items addObject:itemFixed]; 721 | } 722 | 723 | [items addObject:[[UIBarButtonItem alloc] 724 | initWithBarButtonSystemItem:UIBarButtonSystemItemAdd 725 | target:self 726 | action:@selector(onClickAddBookmark)] 727 | ]; 728 | 729 | self.toolbarItems = items; 730 | }]; 731 | } 732 | 733 | 734 | - (void) 735 | userContentController:(WKUserContentController *)userContentController 736 | didReceiveScriptMessage:(WKScriptMessage *)message 737 | { 738 | if (![NSThread isMainThread]) { 739 | NSLog(@"A script message unexpectedly arrived on a non-main thread!"); 740 | } 741 | 742 | NSArray *body = message.body; 743 | 744 | if (message.name == nil || 745 | ![message.name isEqualToString:@"readium"] || 746 | body == nil || 747 | ![body isKindOfClass:[NSArray class]] || 748 | body.count == 0 || 749 | ![body[0] isKindOfClass:[NSString class]]) 750 | { 751 | NSLog(@"Invalid script message! (%@, %@)", message.name, message.body); 752 | return; 753 | } 754 | 755 | NSString *messageName = body[0]; 756 | 757 | if ([messageName isEqualToString:@"mediaOverlayStatusDidChange"]) { 758 | if (body.count < 2 || ![body[1] isKindOfClass:[NSString class]]) { 759 | NSLog(@"The mediaOverlayStatusDidChange payload is invalid!"); 760 | } 761 | else { 762 | [self handleMediaOverlayStatusDidChange:body[1]]; 763 | } 764 | } 765 | else if ([messageName isEqualToString:@"pageDidChange"]) { 766 | if (body.count < 2 || ![body[1] isKindOfClass:[NSString class]]) { 767 | NSLog(@"The pageDidChange payload is invalid!"); 768 | } 769 | else { 770 | [self handlePageDidChange:body[1]]; 771 | } 772 | } 773 | else if ([messageName isEqualToString:@"readerDidInitialize"]) { 774 | [self handleReaderDidInitialize]; 775 | } 776 | } 777 | 778 | 779 | - (void)viewDidLayoutSubviews { 780 | CGSize size = self.view.bounds.size; 781 | 782 | if (m_webViewUI != nil) { 783 | m_webViewUI.frame = self.view.bounds; 784 | } 785 | else if (m_webViewWK != nil) { 786 | self.automaticallyAdjustsScrollViewInsets = NO; 787 | CGFloat y0 = self.topLayoutGuide.length; 788 | CGFloat y1 = size.height - self.bottomLayoutGuide.length; 789 | m_webViewWK.frame = CGRectMake(0, y0, size.width, y1 - y0); 790 | m_webViewWK.scrollView.contentInset = UIEdgeInsetsZero; 791 | m_webViewWK.scrollView.scrollIndicatorInsets = UIEdgeInsetsZero; 792 | } 793 | } 794 | 795 | 796 | - (void)viewWillAppear:(BOOL)animated { 797 | [super viewWillAppear:animated]; 798 | 799 | if (self.navigationController != nil) { 800 | [self.navigationController setToolbarHidden:NO animated:YES]; 801 | } 802 | } 803 | 804 | 805 | - (void)viewWillDisappear:(BOOL)animated { 806 | [super viewWillDisappear:animated]; 807 | 808 | if (self.navigationController != nil) { 809 | [self.navigationController setToolbarHidden:YES animated:YES]; 810 | } 811 | } 812 | 813 | 814 | - (BOOL) 815 | webView:(UIWebView *)webView 816 | shouldStartLoadWithRequest:(NSURLRequest *)request 817 | navigationType:(UIWebViewNavigationType)navigationType 818 | { 819 | BOOL shouldLoad = YES; 820 | NSString *url = request.URL.absoluteString; 821 | NSString *s = @"epubobjc:"; 822 | 823 | // When opening the web inspector from Safari (on desktop OSX), the Javascript sourcemaps are requested and fetched automatically based on the location of their source file counterpart. In other words, no need for intercepting requests below (or via NSURLProtocol), unlike the OSX ReadiumSDK launcher app which requires building custom URL responses containing the sourcemap payload. This needs testing with WKWebView though (right now this works fine with UIWebView because local resources are fetched from the file:// app bundle. 824 | if ([url hasSuffix:@".map"]) { 825 | NSLog(@"%@", [NSString stringWithFormat:@"WEBVIEW-REQUESTED SOURCEMAP: %@", url]); 826 | } 827 | 828 | if ([url hasPrefix:s]) { 829 | url = [url substringFromIndex:s.length]; 830 | shouldLoad = NO; 831 | 832 | s = @"mediaOverlayStatusDidChange?q="; 833 | 834 | if ([url hasPrefix:s]) { 835 | s = [url substringFromIndex:s.length]; 836 | s = [s stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; 837 | [self handleMediaOverlayStatusDidChange:s]; 838 | } 839 | else { 840 | s = @"pageDidChange?q="; 841 | 842 | if ([url hasPrefix:s]) { 843 | s = [url substringFromIndex:s.length]; 844 | s = [s stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; 845 | [self handlePageDidChange:s]; 846 | } 847 | else if ([url isEqualToString:@"readerDidInitialize"]) { 848 | [self handleReaderDidInitialize]; 849 | } 850 | } 851 | } 852 | 853 | return shouldLoad; 854 | } 855 | 856 | - (void)handleAppWillResignActiveNotification:(NSNotification *)notification { 857 | [m_resourceServer stopHTTPServer]; 858 | } 859 | 860 | - (void)handleAppWillEnterForegroundNotification:(NSNotification *)notification { 861 | [m_resourceServer startHTTPServer]; 862 | } 863 | 864 | 865 | @end 866 | -------------------------------------------------------------------------------- /Classes/LocStr.h: -------------------------------------------------------------------------------- 1 | // 2 | // LocStr.h 3 | // SDKLauncher-iOS 4 | // 5 | // Created by Shane Meyer on 2/1/13. 6 | // Copyright (c) 2014 Readium Foundation and/or its licensees. All rights reserved. 7 | // 8 | // Redistribution and use in source and binary forms, with or without modification, 9 | // are permitted provided that the following conditions are met: 10 | // 1. Redistributions of source code must retain the above copyright notice, this 11 | // list of conditions and the following disclaimer. 12 | // 2. Redistributions in binary form must reproduce the above copyright notice, 13 | // this list of conditions and the following disclaimer in the documentation and/or 14 | // other materials provided with the distribution. 15 | // 3. Neither the name of the organization nor the names of its contributors may be 16 | // used to endorse or promote products derived from this software without specific 17 | // prior written permission. 18 | // 19 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 20 | // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 | // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 22 | // IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 23 | // INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 24 | // BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 26 | // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 27 | // OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 28 | // OF THE POSSIBILITY OF SUCH DAMAGE. 29 | 30 | #import 31 | 32 | // Returns a localized string from the appropriate Localizable.strings file. Accepts 33 | // optional string formatting arguments. 34 | NSString *LocStr(NSString *key, ...); 35 | -------------------------------------------------------------------------------- /Classes/LocStr.m: -------------------------------------------------------------------------------- 1 | // 2 | // LocStr.m 3 | // SDKLauncher-iOS 4 | // 5 | // Created by Shane Meyer on 2/1/13. 6 | // Copyright (c) 2014 Readium Foundation and/or its licensees. All rights reserved. 7 | // 8 | // Redistribution and use in source and binary forms, with or without modification, 9 | // are permitted provided that the following conditions are met: 10 | // 1. Redistributions of source code must retain the above copyright notice, this 11 | // list of conditions and the following disclaimer. 12 | // 2. Redistributions in binary form must reproduce the above copyright notice, 13 | // this list of conditions and the following disclaimer in the documentation and/or 14 | // other materials provided with the distribution. 15 | // 3. Neither the name of the organization nor the names of its contributors may be 16 | // used to endorse or promote products derived from this software without specific 17 | // prior written permission. 18 | // 19 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 20 | // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 | // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 22 | // IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 23 | // INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 24 | // BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 26 | // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 27 | // OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 28 | // OF THE POSSIBILITY OF SUCH DAMAGE. 29 | 30 | #import "LocStr.h" 31 | 32 | NSString *LocStr(NSString *key, ...) { 33 | if (key == nil) { 34 | NSLog(@"Got a nil key!"); 35 | } 36 | else { 37 | NSString *s = [[NSBundle mainBundle] localizedStringForKey:key 38 | value:nil table:nil]; 39 | 40 | if (s == nil) { 41 | NSLog(@"Key '%@' has a nil value!", key); 42 | } 43 | else if ([s isEqualToString:key]) { 44 | NSLog(@"Key '%@' not found!", key); 45 | } 46 | else { 47 | // We found the string. Apply the formatting arguments. 48 | 49 | va_list list; 50 | va_start(list, key); 51 | s = [[NSString alloc] initWithFormat:s arguments:list]; 52 | va_end(list); 53 | 54 | return s; 55 | } 56 | } 57 | 58 | return @"NOT FOUND"; 59 | } 60 | -------------------------------------------------------------------------------- /Classes/NavigationElementController.h: -------------------------------------------------------------------------------- 1 | // 2 | // NavigationElementController.h 3 | // SDKLauncher-iOS 4 | // 5 | // Created by Shane Meyer on 4/18/13. 6 | // Copyright (c) 2014 Readium Foundation and/or its licensees. All rights reserved. 7 | // 8 | // Redistribution and use in source and binary forms, with or without modification, 9 | // are permitted provided that the following conditions are met: 10 | // 1. Redistributions of source code must retain the above copyright notice, this 11 | // list of conditions and the following disclaimer. 12 | // 2. Redistributions in binary form must reproduce the above copyright notice, 13 | // this list of conditions and the following disclaimer in the documentation and/or 14 | // other materials provided with the distribution. 15 | // 3. Neither the name of the organization nor the names of its contributors may be 16 | // used to endorse or promote products derived from this software without specific 17 | // prior written permission. 18 | // 19 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 20 | // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 | // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 22 | // IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 23 | // INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 24 | // BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 26 | // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 27 | // OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 28 | // OF THE POSSIBILITY OF SUCH DAMAGE. 29 | 30 | #import "BaseViewController.h" 31 | 32 | @class RDContainer; 33 | @class RDNavigationElement; 34 | @class RDPackage; 35 | 36 | @interface NavigationElementController : BaseViewController < 37 | UITableViewDataSource, 38 | UITableViewDelegate> 39 | { 40 | @private RDContainer *m_container; 41 | @private RDNavigationElement *m_element; 42 | @private RDPackage *m_package; 43 | @private __weak UITableView *m_table; 44 | } 45 | 46 | - (id) 47 | initWithNavigationElement:(RDNavigationElement *)element 48 | container:(RDContainer *)container 49 | package:(RDPackage *)package 50 | title:(NSString *)title; 51 | 52 | @end 53 | -------------------------------------------------------------------------------- /Classes/NavigationElementController.m: -------------------------------------------------------------------------------- 1 | // 2 | // NavigationElementController.m 3 | // SDKLauncher-iOS 4 | // 5 | // Created by Shane Meyer on 4/18/13. 6 | // Copyright (c) 2014 Readium Foundation and/or its licensees. All rights reserved. 7 | // 8 | // Redistribution and use in source and binary forms, with or without modification, 9 | // are permitted provided that the following conditions are met: 10 | // 1. Redistributions of source code must retain the above copyright notice, this 11 | // list of conditions and the following disclaimer. 12 | // 2. Redistributions in binary form must reproduce the above copyright notice, 13 | // this list of conditions and the following disclaimer in the documentation and/or 14 | // other materials provided with the distribution. 15 | // 3. Neither the name of the organization nor the names of its contributors may be 16 | // used to endorse or promote products derived from this software without specific 17 | // prior written permission. 18 | // 19 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 20 | // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 | // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 22 | // IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 23 | // INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 24 | // BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 26 | // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 27 | // OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 28 | // OF THE POSSIBILITY OF SUCH DAMAGE. 29 | 30 | #import "NavigationElementController.h" 31 | #import "EPubViewController.h" 32 | #import "NavigationElementItem.h" 33 | #import "RDContainer.h" 34 | #import "RDNavigationElement.h" 35 | #import "RDPackage.h" 36 | #import "RDSpineItem.h" 37 | 38 | 39 | @interface NavigationElementController () { 40 | @private NSMutableArray *m_items; 41 | } 42 | 43 | - (void)addItem:(NavigationElementItem *)item; 44 | 45 | @end 46 | 47 | 48 | @implementation NavigationElementController 49 | 50 | 51 | - (void)addItem:(NavigationElementItem *)item { 52 | if (item.level >= 16) { 53 | NSLog(@"There are too many levels!"); 54 | return; 55 | } 56 | 57 | [m_items addObject:item]; 58 | 59 | for (RDNavigationElement *e in item.element.children) { 60 | [self addItem:[[NavigationElementItem alloc] 61 | initWithNavigationElement:e level:item.level + 1]]; 62 | } 63 | } 64 | 65 | 66 | - (id) 67 | initWithNavigationElement:(RDNavigationElement *)element 68 | container:(RDContainer *)container 69 | package:(RDPackage *)package 70 | title:(NSString *)title 71 | { 72 | if (element == nil || container == nil || package == nil) { 73 | return nil; 74 | } 75 | 76 | if (self = [super initWithTitle:title navBarHidden:NO]) { 77 | m_container = container; 78 | m_element = element; 79 | m_items = [[NSMutableArray alloc] init]; 80 | m_package = package; 81 | 82 | for (RDNavigationElement *e in element.children) { 83 | [self addItem:[[NavigationElementItem alloc] initWithNavigationElement:e level:0]]; 84 | } 85 | } 86 | 87 | return self; 88 | } 89 | 90 | 91 | - (void)loadView { 92 | self.view = [[UIView alloc] init]; 93 | 94 | UITableView *table = [[UITableView alloc] initWithFrame:CGRectZero style:UITableViewStylePlain]; 95 | m_table = table; 96 | table.dataSource = self; 97 | table.delegate = self; 98 | [self.view addSubview:table]; 99 | } 100 | 101 | 102 | - (UITableViewCell *) 103 | tableView:(UITableView *)tableView 104 | cellForRowAtIndexPath:(NSIndexPath *)indexPath 105 | { 106 | UITableViewCell *cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault 107 | reuseIdentifier:nil]; 108 | 109 | NavigationElementItem *item = [m_items objectAtIndex:indexPath.row]; 110 | 111 | cell.indentationLevel = item.level; 112 | 113 | cell.textLabel.text = [item.element.title stringByTrimmingCharactersInSet:[NSCharacterSet 114 | whitespaceAndNewlineCharacterSet]]; 115 | 116 | if (item.element.content == nil || item.element.content.length == 0) { 117 | cell.selectionStyle = UITableViewCellSelectionStyleNone; 118 | cell.textLabel.textColor = [UIColor colorWithWhite:0 alpha:0.5]; 119 | } 120 | else { 121 | cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator; 122 | } 123 | 124 | return cell; 125 | } 126 | 127 | 128 | - (void) 129 | tableView:(UITableView *)tableView 130 | didSelectRowAtIndexPath:(NSIndexPath *)indexPath 131 | { 132 | NavigationElementItem *item = [m_items objectAtIndex:indexPath.row]; 133 | 134 | if (item.element.content != nil && item.element.content.length > 0) { 135 | EPubViewController *c = [[EPubViewController alloc] 136 | initWithContainer:m_container 137 | package:m_package 138 | navElement:item.element]; 139 | 140 | if (c != nil) { 141 | [self.navigationController pushViewController:c animated:YES]; 142 | } 143 | } 144 | } 145 | 146 | 147 | - (NSInteger) 148 | tableView:(UITableView *)tableView 149 | numberOfRowsInSection:(NSInteger)section 150 | { 151 | return m_items.count; 152 | } 153 | 154 | 155 | - (void)viewDidLayoutSubviews { 156 | m_table.frame = self.view.bounds; 157 | } 158 | 159 | 160 | - (void)viewWillAppear:(BOOL)animated { 161 | [super viewWillAppear:animated]; 162 | 163 | if (m_table.indexPathForSelectedRow != nil) { 164 | [m_table deselectRowAtIndexPath:m_table.indexPathForSelectedRow animated:YES]; 165 | } 166 | } 167 | 168 | 169 | @end 170 | -------------------------------------------------------------------------------- /Classes/NavigationElementItem.h: -------------------------------------------------------------------------------- 1 | // 2 | // NavigationElementItem.h 3 | // SDKLauncher-iOS 4 | // 5 | // Created by Shane Meyer on 3/20/14. 6 | // Copyright (c) 2014 Readium Foundation and/or its licensees. All rights reserved. 7 | // 8 | // Redistribution and use in source and binary forms, with or without modification, 9 | // are permitted provided that the following conditions are met: 10 | // 1. Redistributions of source code must retain the above copyright notice, this 11 | // list of conditions and the following disclaimer. 12 | // 2. Redistributions in binary form must reproduce the above copyright notice, 13 | // this list of conditions and the following disclaimer in the documentation and/or 14 | // other materials provided with the distribution. 15 | // 3. Neither the name of the organization nor the names of its contributors may be 16 | // used to endorse or promote products derived from this software without specific 17 | // prior written permission. 18 | // 19 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 20 | // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 | // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 22 | // IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 23 | // INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 24 | // BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 26 | // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 27 | // OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 28 | // OF THE POSSIBILITY OF SUCH DAMAGE. 29 | 30 | #import 31 | 32 | @class RDNavigationElement; 33 | 34 | @interface NavigationElementItem : NSObject 35 | 36 | @property (nonatomic, readonly) RDNavigationElement *element; 37 | @property (nonatomic, readonly) int level; 38 | 39 | - (id)initWithNavigationElement:(RDNavigationElement *)element level:(int)level; 40 | 41 | @end 42 | -------------------------------------------------------------------------------- /Classes/NavigationElementItem.m: -------------------------------------------------------------------------------- 1 | // 2 | // NavigationElementItem.m 3 | // SDKLauncher-iOS 4 | // 5 | // Created by Shane Meyer on 3/20/14. 6 | // Copyright (c) 2014 Readium Foundation and/or its licensees. All rights reserved. 7 | // 8 | // Redistribution and use in source and binary forms, with or without modification, 9 | // are permitted provided that the following conditions are met: 10 | // 1. Redistributions of source code must retain the above copyright notice, this 11 | // list of conditions and the following disclaimer. 12 | // 2. Redistributions in binary form must reproduce the above copyright notice, 13 | // this list of conditions and the following disclaimer in the documentation and/or 14 | // other materials provided with the distribution. 15 | // 3. Neither the name of the organization nor the names of its contributors may be 16 | // used to endorse or promote products derived from this software without specific 17 | // prior written permission. 18 | // 19 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 20 | // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 | // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 22 | // IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 23 | // INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 24 | // BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 26 | // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 27 | // OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 28 | // OF THE POSSIBILITY OF SUCH DAMAGE. 29 | 30 | #import "NavigationElementItem.h" 31 | #import "RDNavigationElement.h" 32 | 33 | 34 | @interface NavigationElementItem () { 35 | @private RDNavigationElement *m_element; 36 | @private int m_level; 37 | } 38 | 39 | @end 40 | 41 | 42 | @implementation NavigationElementItem 43 | 44 | 45 | @synthesize element = m_element; 46 | @synthesize level = m_level; 47 | 48 | 49 | - (id)initWithNavigationElement:(RDNavigationElement *)element level:(int)level { 50 | m_level = level; 51 | 52 | if (element == nil) { 53 | return nil; 54 | } 55 | 56 | if (self = [super init]) { 57 | m_element = element; 58 | } 59 | 60 | return self; 61 | } 62 | 63 | 64 | @end 65 | -------------------------------------------------------------------------------- /Classes/PackageMetadataController.h: -------------------------------------------------------------------------------- 1 | // 2 | // PackageMetadataController.h 3 | // SDKLauncher-iOS 4 | // 5 | // Created by Shane Meyer on 2/6/13. 6 | // Copyright (c) 2014 Readium Foundation and/or its licensees. All rights reserved. 7 | // 8 | // Redistribution and use in source and binary forms, with or without modification, 9 | // are permitted provided that the following conditions are met: 10 | // 1. Redistributions of source code must retain the above copyright notice, this 11 | // list of conditions and the following disclaimer. 12 | // 2. Redistributions in binary form must reproduce the above copyright notice, 13 | // this list of conditions and the following disclaimer in the documentation and/or 14 | // other materials provided with the distribution. 15 | // 3. Neither the name of the organization nor the names of its contributors may be 16 | // used to endorse or promote products derived from this software without specific 17 | // prior written permission. 18 | // 19 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 20 | // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 | // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 22 | // IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 23 | // INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 24 | // BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 26 | // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 27 | // OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 28 | // OF THE POSSIBILITY OF SUCH DAMAGE. 29 | 30 | #import "BaseViewController.h" 31 | 32 | @class RDPackage; 33 | 34 | @interface PackageMetadataController : BaseViewController { 35 | @private __weak UILabel *m_labelAuthors; 36 | @private __weak UILabel *m_labelCopyrightOwner; 37 | @private __weak UILabel *m_labelFullTitle; 38 | @private __weak UILabel *m_labelISBN; 39 | @private __weak UILabel *m_labelLanguage; 40 | @private __weak UILabel *m_labelModificationDate; 41 | @private __weak UILabel *m_labelPackageID; 42 | @private __weak UILabel *m_labelSource; 43 | @private __weak UILabel *m_labelSubjects; 44 | @private __weak UILabel *m_labelSubtitle; 45 | @private __weak UILabel *m_labelTitle; 46 | @private RDPackage *m_package; 47 | @private __weak UIScrollView *m_scroll; 48 | } 49 | 50 | - (id)initWithPackage:(RDPackage *)package; 51 | 52 | @end 53 | -------------------------------------------------------------------------------- /Classes/PackageMetadataController.m: -------------------------------------------------------------------------------- 1 | // 2 | // PackageMetadataController.m 3 | // SDKLauncher-iOS 4 | // 5 | // Created by Shane Meyer on 2/6/13. 6 | // Copyright (c) 2014 Readium Foundation and/or its licensees. All rights reserved. 7 | // 8 | // Redistribution and use in source and binary forms, with or without modification, 9 | // are permitted provided that the following conditions are met: 10 | // 1. Redistributions of source code must retain the above copyright notice, this 11 | // list of conditions and the following disclaimer. 12 | // 2. Redistributions in binary form must reproduce the above copyright notice, 13 | // this list of conditions and the following disclaimer in the documentation and/or 14 | // other materials provided with the distribution. 15 | // 3. Neither the name of the organization nor the names of its contributors may be 16 | // used to endorse or promote products derived from this software without specific 17 | // prior written permission. 18 | // 19 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 20 | // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 | // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 22 | // IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 23 | // INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 24 | // BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 26 | // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 27 | // OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 28 | // OF THE POSSIBILITY OF SUCH DAMAGE. 29 | 30 | #import "PackageMetadataController.h" 31 | #import "RDPackage.h" 32 | 33 | 34 | @interface PackageMetadataController() 35 | 36 | - (UILabel *)addLabelWithText:(NSString *)text; 37 | 38 | @end 39 | 40 | 41 | @implementation PackageMetadataController 42 | 43 | 44 | - (UILabel *)addLabelWithText:(NSString *)text { 45 | UILabel *label = [[UILabel alloc] init]; 46 | label.backgroundColor = [UIColor clearColor]; 47 | label.font = [UIFont systemFontOfSize:16]; 48 | label.numberOfLines = 0; 49 | label.text = text; 50 | label.textColor = [UIColor blackColor]; 51 | [m_scroll addSubview:label]; 52 | return label; 53 | } 54 | 55 | 56 | - (id)initWithPackage:(RDPackage *)package { 57 | if (package == nil) { 58 | return nil; 59 | } 60 | 61 | if (self = [super initWithTitle:LocStr(@"METADATA") navBarHidden:NO]) { 62 | m_package = package; 63 | } 64 | 65 | return self; 66 | } 67 | 68 | 69 | - (void)loadView { 70 | self.view = [[UIView alloc] init]; 71 | self.view.backgroundColor = [UIColor whiteColor]; 72 | 73 | UIScrollView *scroll = [[UIScrollView alloc] init]; 74 | m_scroll = scroll; 75 | scroll.alwaysBounceVertical = YES; 76 | [self.view addSubview:scroll]; 77 | 78 | m_labelTitle = [self addLabelWithText: 79 | LocStr(@"METADATA_TITLE", m_package.title)]; 80 | 81 | m_labelFullTitle = [self addLabelWithText: 82 | LocStr(@"METADATA_FULL_TITLE", m_package.fullTitle)]; 83 | 84 | m_labelSubtitle = [self addLabelWithText: 85 | LocStr(@"METADATA_SUBTITLE", m_package.subtitle)]; 86 | 87 | m_labelAuthors = [self addLabelWithText: 88 | LocStr(@"METADATA_AUTHORS", m_package.authors)]; 89 | 90 | m_labelLanguage = [self addLabelWithText: 91 | LocStr(@"METADATA_LANGUAGE", m_package.language)]; 92 | 93 | m_labelSource = [self addLabelWithText: 94 | LocStr(@"METADATA_SOURCE", m_package.source)]; 95 | 96 | m_labelCopyrightOwner = [self addLabelWithText: 97 | LocStr(@"METADATA_COPYRIGHT_OWNER", m_package.copyrightOwner)]; 98 | 99 | m_labelModificationDate = [self addLabelWithText: 100 | LocStr(@"METADATA_MODIFICATION_DATE", m_package.modificationDateString)]; 101 | 102 | m_labelPackageID = [self addLabelWithText: 103 | LocStr(@"METADATA_PACKAGE_ID", m_package.packageID)]; 104 | 105 | m_labelISBN = [self addLabelWithText: 106 | LocStr(@"METADATA_ISBN", m_package.isbn)]; 107 | 108 | m_labelSubjects = [self addLabelWithText: 109 | LocStr(@"METADATA_SUBJECTS", [m_package.subjects componentsJoinedByString:@", "])]; 110 | } 111 | 112 | 113 | - (void)viewDidLayoutSubviews { 114 | CGSize size = self.view.bounds.size; 115 | CGFloat margin = 16; 116 | CGFloat y = 0; 117 | CGFloat width = size.width - 2.0 * margin; 118 | 119 | m_scroll.frame = self.view.bounds; 120 | 121 | m_labelTitle.frame = CGRectMake(margin, y + margin, width, 1); 122 | [m_labelTitle sizeToFit]; 123 | y = CGRectGetMaxY(m_labelTitle.frame); 124 | 125 | m_labelFullTitle.frame = CGRectMake(margin, y + margin, width, 1); 126 | [m_labelFullTitle sizeToFit]; 127 | y = CGRectGetMaxY(m_labelFullTitle.frame); 128 | 129 | m_labelSubtitle.frame = CGRectMake(margin, y + margin, width, 1); 130 | [m_labelSubtitle sizeToFit]; 131 | y = CGRectGetMaxY(m_labelSubtitle.frame); 132 | 133 | m_labelAuthors.frame = CGRectMake(margin, y + margin, width, 1); 134 | [m_labelAuthors sizeToFit]; 135 | y = CGRectGetMaxY(m_labelAuthors.frame); 136 | 137 | m_labelLanguage.frame = CGRectMake(margin, y + margin, width, 1); 138 | [m_labelLanguage sizeToFit]; 139 | y = CGRectGetMaxY(m_labelLanguage.frame); 140 | 141 | m_labelSource.frame = CGRectMake(margin, y + margin, width, 1); 142 | [m_labelSource sizeToFit]; 143 | y = CGRectGetMaxY(m_labelSource.frame); 144 | 145 | m_labelCopyrightOwner.frame = CGRectMake(margin, y + margin, width, 1); 146 | [m_labelCopyrightOwner sizeToFit]; 147 | y = CGRectGetMaxY(m_labelCopyrightOwner.frame); 148 | 149 | m_labelModificationDate.frame = CGRectMake(margin, y + margin, width, 1); 150 | [m_labelModificationDate sizeToFit]; 151 | y = CGRectGetMaxY(m_labelModificationDate.frame); 152 | 153 | m_labelPackageID.frame = CGRectMake(margin, y + margin, width, 1); 154 | [m_labelPackageID sizeToFit]; 155 | y = CGRectGetMaxY(m_labelPackageID.frame); 156 | 157 | m_labelISBN.frame = CGRectMake(margin, y + margin, width, 1); 158 | [m_labelISBN sizeToFit]; 159 | y = CGRectGetMaxY(m_labelISBN.frame); 160 | 161 | m_labelSubjects.frame = CGRectMake(margin, y + margin, width, 1); 162 | [m_labelSubjects sizeToFit]; 163 | y = CGRectGetMaxY(m_labelSubjects.frame); 164 | 165 | m_scroll.contentSize = CGSizeMake(size.width, y + margin); 166 | } 167 | 168 | 169 | @end 170 | -------------------------------------------------------------------------------- /Classes/Settings.h: -------------------------------------------------------------------------------- 1 | // 2 | // Settings.h 3 | // SDKLauncher-iOS 4 | // 5 | // Created by Shane Meyer on 4/20/13. 6 | // Copyright (c) 2014 Readium Foundation and/or its licensees. All rights reserved. 7 | // 8 | // Redistribution and use in source and binary forms, with or without modification, 9 | // are permitted provided that the following conditions are met: 10 | // 1. Redistributions of source code must retain the above copyright notice, this 11 | // list of conditions and the following disclaimer. 12 | // 2. Redistributions in binary form must reproduce the above copyright notice, 13 | // this list of conditions and the following disclaimer in the documentation and/or 14 | // other materials provided with the distribution. 15 | // 3. Neither the name of the organization nor the names of its contributors may be 16 | // used to endorse or promote products derived from this software without specific 17 | // prior written permission. 18 | // 19 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 20 | // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 | // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 22 | // IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 23 | // INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 24 | // BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 26 | // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 27 | // OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 28 | // OF THE POSSIBILITY OF SUCH DAMAGE. 29 | 30 | #import 31 | #import "EPubSettings.h" 32 | 33 | @interface Settings : NSObject 34 | 35 | @property (nonatomic, strong) NSDictionary *bookmarks; 36 | @property (nonatomic, assign) CGFloat columnGap; 37 | @property (nonatomic, assign) CGFloat fontScale; 38 | @property (nonatomic, assign) EPubSettingsScroll scroll; 39 | @property (nonatomic, assign) EPubSettingsSyntheticSpread syntheticSpread; 40 | 41 | + (Settings *)shared; 42 | 43 | @end 44 | -------------------------------------------------------------------------------- /Classes/Settings.m: -------------------------------------------------------------------------------- 1 | // 2 | // Settings.m 3 | // SDKLauncher-iOS 4 | // 5 | // Created by Shane Meyer on 4/20/13. 6 | // Copyright (c) 2014 Readium Foundation and/or its licensees. All rights reserved. 7 | // 8 | // Redistribution and use in source and binary forms, with or without modification, 9 | // are permitted provided that the following conditions are met: 10 | // 1. Redistributions of source code must retain the above copyright notice, this 11 | // list of conditions and the following disclaimer. 12 | // 2. Redistributions in binary form must reproduce the above copyright notice, 13 | // this list of conditions and the following disclaimer in the documentation and/or 14 | // other materials provided with the distribution. 15 | // 3. Neither the name of the organization nor the names of its contributors may be 16 | // used to endorse or promote products derived from this software without specific 17 | // prior written permission. 18 | // 19 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 20 | // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 | // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 22 | // IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 23 | // INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 24 | // BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 26 | // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 27 | // OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 28 | // OF THE POSSIBILITY OF SUCH DAMAGE. 29 | 30 | #import "Settings.h" 31 | 32 | 33 | #define kKeyBookmarks @"SDKLauncherBookmarks" 34 | #define kKeyColumnGap @"SDKLauncherColumnGap" 35 | #define kKeyFontScale @"SDKLauncherFontScale" 36 | #define kKeyScroll @"SDKLauncherScroll" 37 | #define kKeySyntheticSpread @"SDKLauncherSyntheticSpread" 38 | 39 | 40 | @interface Settings () 41 | 42 | - (BOOL)boolForKey:(NSString *)key defaultValue:(BOOL)defaultValue; 43 | - (CGFloat)cgFloatForKey:(NSString *)key defaultValue:(CGFloat)defaultValue; 44 | - (void)setCGFloat:(CGFloat)value forKey:(NSString *)key; 45 | 46 | @end 47 | 48 | 49 | @implementation Settings 50 | 51 | 52 | - (NSDictionary *)bookmarks { 53 | return [[NSUserDefaults standardUserDefaults] dictionaryForKey:kKeyBookmarks]; 54 | } 55 | 56 | 57 | - (BOOL)boolForKey:(NSString *)key defaultValue:(BOOL)defaultValue { 58 | NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; 59 | 60 | if ([defaults objectForKey:key] == nil) { 61 | return defaultValue; 62 | } 63 | 64 | return [defaults boolForKey:key]; 65 | } 66 | 67 | 68 | - (CGFloat)cgFloatForKey:(NSString *)key defaultValue:(CGFloat)defaultValue { 69 | NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; 70 | 71 | if ([defaults objectForKey:key] == nil) { 72 | return defaultValue; 73 | } 74 | 75 | if (sizeof(CGFloat) == sizeof(float)) { 76 | return [defaults floatForKey:key]; 77 | } 78 | 79 | return [defaults doubleForKey:key]; 80 | } 81 | 82 | 83 | - (CGFloat)columnGap { 84 | return [self cgFloatForKey:kKeyColumnGap defaultValue:20]; 85 | } 86 | 87 | 88 | - (CGFloat)fontScale { 89 | return [self cgFloatForKey:kKeyFontScale defaultValue:1]; 90 | } 91 | 92 | 93 | - (EPubSettingsScroll)scroll { 94 | NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; 95 | NSNumber *number = [defaults objectForKey:kKeyScroll]; 96 | return (number == nil || ![number isKindOfClass:[NSNumber class]]) ? 97 | EPubSettingsScrollAuto : number.integerValue; 98 | } 99 | 100 | 101 | - (void)setBookmarks:(NSDictionary *)bookmarks { 102 | if (bookmarks == nil) { 103 | [[NSUserDefaults standardUserDefaults] removeObjectForKey:kKeyBookmarks]; 104 | } 105 | else { 106 | [[NSUserDefaults standardUserDefaults] setObject:bookmarks forKey:kKeyBookmarks]; 107 | } 108 | } 109 | 110 | 111 | - (void)setCGFloat:(CGFloat)value forKey:(NSString *)key { 112 | if (sizeof(CGFloat) == sizeof(float)) { 113 | [[NSUserDefaults standardUserDefaults] setFloat:value forKey:key]; 114 | } 115 | else { 116 | [[NSUserDefaults standardUserDefaults] setDouble:value forKey:key]; 117 | } 118 | } 119 | 120 | 121 | - (void)setColumnGap:(CGFloat)value { 122 | [self setCGFloat:value forKey:kKeyColumnGap]; 123 | } 124 | 125 | 126 | - (void)setFontScale:(CGFloat)value { 127 | [self setCGFloat:value forKey:kKeyFontScale]; 128 | } 129 | 130 | 131 | - (void)setScroll:(EPubSettingsScroll)value { 132 | [[NSUserDefaults standardUserDefaults] setInteger:value forKey:kKeyScroll]; 133 | } 134 | 135 | 136 | - (void)setSyntheticSpread:(EPubSettingsSyntheticSpread)value { 137 | [[NSUserDefaults standardUserDefaults] setInteger:value forKey:kKeySyntheticSpread]; 138 | } 139 | 140 | 141 | + (Settings *)shared { 142 | static Settings *shared = nil; 143 | 144 | if (shared == nil) { 145 | shared = [[Settings alloc] init]; 146 | } 147 | 148 | return shared; 149 | } 150 | 151 | 152 | - (EPubSettingsSyntheticSpread)syntheticSpread { 153 | NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; 154 | NSNumber *number = [defaults objectForKey:kKeySyntheticSpread]; 155 | return (number == nil || ![number isKindOfClass:[NSNumber class]]) ? 156 | EPubSettingsSyntheticSpreadAuto : number.integerValue; 157 | } 158 | 159 | 160 | @end 161 | -------------------------------------------------------------------------------- /Classes/SpineItemListController.h: -------------------------------------------------------------------------------- 1 | // 2 | // SpineItemListController.h 3 | // SDKLauncher-iOS 4 | // 5 | // Created by Shane Meyer on 2/6/13. 6 | // Copyright (c) 2014 Readium Foundation and/or its licensees. All rights reserved. 7 | // 8 | // Redistribution and use in source and binary forms, with or without modification, 9 | // are permitted provided that the following conditions are met: 10 | // 1. Redistributions of source code must retain the above copyright notice, this 11 | // list of conditions and the following disclaimer. 12 | // 2. Redistributions in binary form must reproduce the above copyright notice, 13 | // this list of conditions and the following disclaimer in the documentation and/or 14 | // other materials provided with the distribution. 15 | // 3. Neither the name of the organization nor the names of its contributors may be 16 | // used to endorse or promote products derived from this software without specific 17 | // prior written permission. 18 | // 19 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 20 | // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 | // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 22 | // IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 23 | // INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 24 | // BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 26 | // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 27 | // OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 28 | // OF THE POSSIBILITY OF SUCH DAMAGE. 29 | 30 | #import "BaseViewController.h" 31 | 32 | @class RDContainer; 33 | @class RDPackage; 34 | 35 | @interface SpineItemListController : BaseViewController < 36 | UITableViewDataSource, 37 | UITableViewDelegate> 38 | { 39 | @private RDContainer *m_container; 40 | @private RDPackage *m_package; 41 | @private __weak UITableView *m_table; 42 | } 43 | 44 | - (id)initWithContainer:(RDContainer *)container package:(RDPackage *)package; 45 | 46 | @end 47 | -------------------------------------------------------------------------------- /Classes/SpineItemListController.m: -------------------------------------------------------------------------------- 1 | // 2 | // SpineItemListController.m 3 | // SDKLauncher-iOS 4 | // 5 | // Created by Shane Meyer on 2/6/13. 6 | // Copyright (c) 2014 Readium Foundation and/or its licensees. All rights reserved. 7 | // 8 | // Redistribution and use in source and binary forms, with or without modification, 9 | // are permitted provided that the following conditions are met: 10 | // 1. Redistributions of source code must retain the above copyright notice, this 11 | // list of conditions and the following disclaimer. 12 | // 2. Redistributions in binary form must reproduce the above copyright notice, 13 | // this list of conditions and the following disclaimer in the documentation and/or 14 | // other materials provided with the distribution. 15 | // 3. Neither the name of the organization nor the names of its contributors may be 16 | // used to endorse or promote products derived from this software without specific 17 | // prior written permission. 18 | // 19 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 20 | // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 | // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 22 | // IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 23 | // INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 24 | // BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 26 | // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 27 | // OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 28 | // OF THE POSSIBILITY OF SUCH DAMAGE. 29 | 30 | #import "SpineItemListController.h" 31 | #import "EPubViewController.h" 32 | #import "RDContainer.h" 33 | #import "RDPackage.h" 34 | #import "RDSpineItem.h" 35 | 36 | 37 | @implementation SpineItemListController 38 | 39 | 40 | - (id)initWithContainer:(RDContainer *)container package:(RDPackage *)package { 41 | if (container == nil || package == nil) { 42 | return nil; 43 | } 44 | 45 | if (self = [super initWithTitle:LocStr(@"SPINE_ITEMS") navBarHidden:NO]) { 46 | m_container = container; 47 | m_package = package; 48 | } 49 | 50 | return self; 51 | } 52 | 53 | 54 | - (void)loadView { 55 | self.view = [[UIView alloc] init]; 56 | 57 | UITableView *table = [[UITableView alloc] initWithFrame:CGRectZero style:UITableViewStylePlain]; 58 | m_table = table; 59 | table.dataSource = self; 60 | table.delegate = self; 61 | [self.view addSubview:table]; 62 | } 63 | 64 | 65 | - (UITableViewCell *) 66 | tableView:(UITableView *)tableView 67 | cellForRowAtIndexPath:(NSIndexPath *)indexPath 68 | { 69 | UITableViewCell *cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault 70 | reuseIdentifier:nil]; 71 | cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator; 72 | RDSpineItem *spineItem = [m_package.spineItems objectAtIndex:indexPath.row]; 73 | cell.textLabel.text = spineItem.idref; 74 | return cell; 75 | } 76 | 77 | 78 | - (void) 79 | tableView:(UITableView *)tableView 80 | didSelectRowAtIndexPath:(NSIndexPath *)indexPath 81 | { 82 | RDSpineItem *spineItem = [m_package.spineItems objectAtIndex:indexPath.row]; 83 | EPubViewController *c = [[EPubViewController alloc] 84 | initWithContainer:m_container 85 | package:m_package 86 | spineItem:spineItem 87 | cfi:nil]; 88 | [self.navigationController pushViewController:c animated:YES]; 89 | } 90 | 91 | 92 | - (NSInteger) 93 | tableView:(UITableView *)tableView 94 | numberOfRowsInSection:(NSInteger)section 95 | { 96 | return m_package.spineItems.count; 97 | } 98 | 99 | 100 | - (void)viewDidLayoutSubviews { 101 | m_table.frame = self.view.bounds; 102 | } 103 | 104 | 105 | - (void)viewWillAppear:(BOOL)animated { 106 | [super viewWillAppear:animated]; 107 | 108 | if (m_table.indexPathForSelectedRow != nil) { 109 | [m_table deselectRowAtIndexPath:m_table.indexPathForSelectedRow animated:YES]; 110 | } 111 | } 112 | 113 | 114 | @end 115 | -------------------------------------------------------------------------------- /Classes/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // SDKLauncher-iOS 4 | // 5 | // Created by Shane Meyer on 2/1/13. 6 | // Copyright (c) 2014 Readium Foundation and/or its licensees. All rights reserved. 7 | // 8 | // Redistribution and use in source and binary forms, with or without modification, 9 | // are permitted provided that the following conditions are met: 10 | // 1. Redistributions of source code must retain the above copyright notice, this 11 | // list of conditions and the following disclaimer. 12 | // 2. Redistributions in binary form must reproduce the above copyright notice, 13 | // this list of conditions and the following disclaimer in the documentation and/or 14 | // other materials provided with the distribution. 15 | // 3. Neither the name of the organization nor the names of its contributors may be 16 | // used to endorse or promote products derived from this software without specific 17 | // prior written permission. 18 | // 19 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 20 | // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 | // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 22 | // IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 23 | // INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 24 | // BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 26 | // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 27 | // OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 28 | // OF THE POSSIBILITY OF SUCH DAMAGE. 29 | 30 | #import 31 | #import "AppDelegate.h" 32 | 33 | int main(int argc, char *argv[]) { 34 | @autoreleasepool { 35 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /Other/Icon-512@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/readium/SDKLauncher-iOS/3d1fceb3ff096370d9bc7df4a874ac9e4e83db90/Other/Icon-512@2x.png -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | _Note: Please don't use the zip download feature on this repo as this repo uses submodules and this is not supported at present by github and will result in an incomplete copy of the repo._ 2 | 3 | ## SDKLauncher-iOS 4 | 5 | A small iOS application to serve as a launcher/testbed for the Readium SDK. 6 | 7 | ## Jenkins build status 8 | 9 | * master [![Build Status](http://jenkinsmaster.datalogics-cloud.com:8080/buildStatus/icon?job=Readium-SDK-Launcher-iOS-master)](http://jenkinsmaster.datalogics-cloud:8080/view/Readium-Launcher/job/Readium-SDK-Launcher-iOS-master/) 10 | * develop [![Build Status](http://jenkinsmaster.datalogics-cloud.com:8080/buildStatus/icon?job=Readium-SDK-Launcher-iOS-develop)](http://jenkinsmaster.datalogics-cloud:8080/view/Readium-Launcher/job/Readium-SDK-Launcher-iOS-develop/) 11 | 12 | Licensing info 13 | ---------------- 14 | Licensing information can be found in the file license.txt in the root of the repo, as well as in the source code itself. 15 | -------------------------------------------------------------------------------- /Resources/Default-568h@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/readium/SDKLauncher-iOS/3d1fceb3ff096370d9bc7df4a874ac9e4e83db90/Resources/Default-568h@2x.png -------------------------------------------------------------------------------- /Resources/Default-Landscape.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/readium/SDKLauncher-iOS/3d1fceb3ff096370d9bc7df4a874ac9e4e83db90/Resources/Default-Landscape.png -------------------------------------------------------------------------------- /Resources/Default-Landscape@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/readium/SDKLauncher-iOS/3d1fceb3ff096370d9bc7df4a874ac9e4e83db90/Resources/Default-Landscape@2x.png -------------------------------------------------------------------------------- /Resources/Default-Portrait.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/readium/SDKLauncher-iOS/3d1fceb3ff096370d9bc7df4a874ac9e4e83db90/Resources/Default-Portrait.png -------------------------------------------------------------------------------- /Resources/Default-Portrait@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/readium/SDKLauncher-iOS/3d1fceb3ff096370d9bc7df4a874ac9e4e83db90/Resources/Default-Portrait@2x.png -------------------------------------------------------------------------------- /Resources/Default.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/readium/SDKLauncher-iOS/3d1fceb3ff096370d9bc7df4a874ac9e4e83db90/Resources/Default.png -------------------------------------------------------------------------------- /Resources/Default@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/readium/SDKLauncher-iOS/3d1fceb3ff096370d9bc7df4a874ac9e4e83db90/Resources/Default@2x.png -------------------------------------------------------------------------------- /Resources/Icon-29.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/readium/SDKLauncher-iOS/3d1fceb3ff096370d9bc7df4a874ac9e4e83db90/Resources/Icon-29.png -------------------------------------------------------------------------------- /Resources/Icon-29@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/readium/SDKLauncher-iOS/3d1fceb3ff096370d9bc7df4a874ac9e4e83db90/Resources/Icon-29@2x.png -------------------------------------------------------------------------------- /Resources/Icon-40.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/readium/SDKLauncher-iOS/3d1fceb3ff096370d9bc7df4a874ac9e4e83db90/Resources/Icon-40.png -------------------------------------------------------------------------------- /Resources/Icon-40@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/readium/SDKLauncher-iOS/3d1fceb3ff096370d9bc7df4a874ac9e4e83db90/Resources/Icon-40@2x.png -------------------------------------------------------------------------------- /Resources/Icon-50.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/readium/SDKLauncher-iOS/3d1fceb3ff096370d9bc7df4a874ac9e4e83db90/Resources/Icon-50.png -------------------------------------------------------------------------------- /Resources/Icon-50@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/readium/SDKLauncher-iOS/3d1fceb3ff096370d9bc7df4a874ac9e4e83db90/Resources/Icon-50@2x.png -------------------------------------------------------------------------------- /Resources/Icon-57.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/readium/SDKLauncher-iOS/3d1fceb3ff096370d9bc7df4a874ac9e4e83db90/Resources/Icon-57.png -------------------------------------------------------------------------------- /Resources/Icon-57@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/readium/SDKLauncher-iOS/3d1fceb3ff096370d9bc7df4a874ac9e4e83db90/Resources/Icon-57@2x.png -------------------------------------------------------------------------------- /Resources/Icon-60@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/readium/SDKLauncher-iOS/3d1fceb3ff096370d9bc7df4a874ac9e4e83db90/Resources/Icon-60@2x.png -------------------------------------------------------------------------------- /Resources/Icon-72.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/readium/SDKLauncher-iOS/3d1fceb3ff096370d9bc7df4a874ac9e4e83db90/Resources/Icon-72.png -------------------------------------------------------------------------------- /Resources/Icon-72@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/readium/SDKLauncher-iOS/3d1fceb3ff096370d9bc7df4a874ac9e4e83db90/Resources/Icon-72@2x.png -------------------------------------------------------------------------------- /Resources/Icon-76.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/readium/SDKLauncher-iOS/3d1fceb3ff096370d9bc7df4a874ac9e4e83db90/Resources/Icon-76.png -------------------------------------------------------------------------------- /Resources/Icon-76@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/readium/SDKLauncher-iOS/3d1fceb3ff096370d9bc7df4a874ac9e4e83db90/Resources/Icon-76@2x.png -------------------------------------------------------------------------------- /Resources/annotations.css: -------------------------------------------------------------------------------- 1 | /* The z-index is to ensure that the bookmark is accessible even if it's overlayed on a highlight/underline of some type */ 2 | .comment { 3 | /* 4 | background-image : url("/images/comment_clickable_icon.png"); 5 | background-repeat : no-repeat; 6 | */ 7 | opacity : 0.5; 8 | z-index : 10; 9 | } 10 | .hover-comment { 11 | /* 12 | background-image : url("/images/comment_clickable_icon.png"); 13 | background-repeat : no-repeat; 14 | */ 15 | opacity : 1.0; 16 | z-index : 10; 17 | } 18 | 19 | .bookmark { 20 | position : fixed; 21 | top : "0px"; 22 | right : "0px"; 23 | background-color: red; 24 | } 25 | 26 | .highlight { 27 | position: absolute; 28 | opacity: 0.2; 29 | background-color: red; 30 | } 31 | 32 | .hover-highlight { 33 | position: absolute; 34 | opacity: 0.4; 35 | background-color: red; 36 | } 37 | 38 | .underline-range { 39 | position: absolute; 40 | } 41 | 42 | .underline-range > .underline { 43 | position: relative; 44 | height: 15%; 45 | opacity: 0.2; 46 | background-color: red; 47 | } 48 | 49 | .underline-range > .hover-underline { 50 | position: relative; 51 | height: 15%; 52 | opacity: 0.4; 53 | background-color: red; 54 | } 55 | 56 | .underline-range > .transparent-part { 57 | position: relative; 58 | height: 85%; 59 | background-color: transparent; 60 | } -------------------------------------------------------------------------------- /Resources/childrens-literature-20130206.epub: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/readium/SDKLauncher-iOS/3d1fceb3ff096370d9bc7df4a874ac9e4e83db90/Resources/childrens-literature-20130206.epub -------------------------------------------------------------------------------- /Resources/en.lproj/Localizable.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/readium/SDKLauncher-iOS/3d1fceb3ff096370d9bc7df4a874ac9e4e83db90/Resources/en.lproj/Localizable.strings -------------------------------------------------------------------------------- /Resources/epub30-test-0120-20131022.epub: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/readium/SDKLauncher-iOS/3d1fceb3ff096370d9bc7df4a874ac9e4e83db90/Resources/epub30-test-0120-20131022.epub -------------------------------------------------------------------------------- /Resources/epub30-test-0220-20131022.epub: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/readium/SDKLauncher-iOS/3d1fceb3ff096370d9bc7df4a874ac9e4e83db90/Resources/epub30-test-0220-20131022.epub -------------------------------------------------------------------------------- /Resources/epubReadingSystem.epub: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/readium/SDKLauncher-iOS/3d1fceb3ff096370d9bc7df4a874ac9e4e83db90/Resources/epubReadingSystem.epub -------------------------------------------------------------------------------- /Resources/epubReadingSystem.js: -------------------------------------------------------------------------------- 1 | ReadiumSDK.READIUM_iOS_sha = ''; 2 | ReadiumSDK.READIUM_iOS_tag = ''; 3 | ReadiumSDK.READIUM_iOS_clean = ''; 4 | ReadiumSDK.READIUM_iOS_version = ''; 5 | ReadiumSDK.READIUM_iOS_branch = ''; 6 | ReadiumSDK.READIUM_iOS_release = ''; 7 | ReadiumSDK.READIUM_iOS_timestamp = ''; 8 | ReadiumSDK.READIUM_SDK_sha = ''; 9 | ReadiumSDK.READIUM_SDK_tag = ''; 10 | ReadiumSDK.READIUM_SDK_clean = ''; 11 | ReadiumSDK.READIUM_SDK_version = ''; 12 | ReadiumSDK.READIUM_SDK_branch = ''; 13 | ReadiumSDK.READIUM_SDK_release = ''; 14 | ReadiumSDK.READIUM_SDK_timestamp = ''; 15 | ReadiumSDK.READIUM_SHARED_JS_sha = ''; 16 | ReadiumSDK.READIUM_SHARED_JS_tag = ''; 17 | ReadiumSDK.READIUM_SHARED_JS_clean = ''; 18 | ReadiumSDK.READIUM_SHARED_JS_version = ''; 19 | ReadiumSDK.READIUM_SHARED_JS_branch = ''; 20 | ReadiumSDK.READIUM_SHARED_JS_release = ''; 21 | ReadiumSDK.READIUM_SHARED_JS_timestamp = ''; 22 | ReadiumSDK.READIUM_dateTimeString = ''; 23 | -------------------------------------------------------------------------------- /Resources/epubReadingSystem.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | echo "###########################################" 4 | echo "###########################################" 5 | 6 | pwd=`pwd` 7 | echo "Path:" 8 | echo "${pwd}" 9 | echo "------" 10 | 11 | JS_FILE="${pwd}/Resources/epubReadingSystem_.js" 12 | test -z "${CONTENTS_FOLDER_PATH}" || JS_FILE="${TARGET_BUILD_DIR}/${CONTENTS_FOLDER_PATH}/epubReadingSystem.js" 13 | echo "Javascript output:" 14 | echo "${JS_FILE}" 15 | test -z "${CONTENTS_FOLDER_PATH}" && echo "WARNING: file 'epubReadingSystem.js' will NOT be updated in XCode build folder! (running script from raw command line?)" 16 | echo "------" 17 | 18 | FIRST="" 19 | 20 | GitDo() { 21 | ROOT_DIR=$1 22 | INTERMEDIATE_DIR=$2 23 | GIT_SUBMODULE=$3 24 | SUB_DIR="${ROOT_DIR}${INTERMEDIATE_DIR}${GIT_SUBMODULE}" 25 | TARGET_PREFIX=$4 26 | 27 | cd "${SUB_DIR}" 28 | 29 | echo "=========================" 30 | echo "Git target prefix:" 31 | echo "${TARGET_PREFIX}" 32 | echo "------" 33 | 34 | GIT_DIR="${ROOT_DIR}/.git" 35 | echo "Git directory:" 36 | echo "${GIT_DIR}" 37 | echo "------" 38 | 39 | echo "Git submodule directory:" 40 | echo "${SUB_DIR}" 41 | echo "------" 42 | 43 | # We use "cd" instead! (more reliable, due to vendor submodules not necessarily setup the way we do it internally for Readium) 44 | GIT_DIR_CWD="" 45 | # GIT_DIR_CWD="--git-dir=${GIT_DIR} --work-tree=${SUB_DIR}" 46 | # echo "Git path spec:" 47 | # echo "${GIT_DIR_CWD}" 48 | # echo "------" 49 | 50 | GIT_HEAD_PATH="${GIT_DIR}/HEAD" 51 | test -f "${SUB_DIR}/HEAD" && GIT_HEAD_PATH="${SUB_DIR}/HEAD" 52 | test -f "${GIT_DIR}/modules/${GIT_SUBMODULE}/HEAD" && GIT_HEAD_PATH="${GIT_DIR}/modules/${GIT_SUBMODULE}/HEAD" 53 | echo "Git HEAD path:" 54 | echo "${GIT_HEAD_PATH}"; 55 | echo "------" 56 | 57 | GIT_HEAD=`cat "${GIT_HEAD_PATH}"` 58 | echo "Git HEAD:" 59 | echo "${GIT_HEAD}"; 60 | echo "------" 61 | 62 | test "${GIT_HEAD#'ref: '}" != "${GIT_HEAD}" && echo "(attached head)" && GIT_SHA=`git ${GIT_DIR_CWD} rev-parse --verify HEAD` 63 | test "${GIT_HEAD#'ref: '}" == "${GIT_HEAD}" && echo "(detached head)" && GIT_SHA="${GIT_HEAD}" 64 | 65 | echo "Git SHA:" 66 | echo "${GIT_SHA}" 67 | echo "------" 68 | 69 | GIT_TAG=`git ${GIT_DIR_CWD} describe --tags --long ${GIT_SHA}` 70 | echo "Git TAG:" 71 | echo "${GIT_TAG}" 72 | echo "------" 73 | 74 | GIT_STATUS=`git ${GIT_DIR_CWD} status --porcelain` 75 | echo "Git STATUS:" 76 | echo "${GIT_STATUS}" 77 | echo "------" 78 | 79 | GIT_CLEAN=false 80 | test -z "${GIT_STATUS}" && GIT_CLEAN=true 81 | echo "Git CLEAN:" 82 | echo "${GIT_CLEAN}" 83 | echo "------" 84 | 85 | GIT_BRANCH=`git for-each-ref --format="%(refname:short) %(objectname)" 'refs/heads/' | grep $(git rev-parse HEAD) | cut -d " " -f 1` 86 | echo "Git BRANCH:" 87 | echo "${GIT_BRANCH}" 88 | echo "------" 89 | 90 | GIT_VERSION=0.0.0 91 | GIT_RELEASE=false 92 | 93 | #GIT_TIMESTAMP=`date '+%s'` 94 | GIT_TIMESTAMP=$(($(date '+%s') * 1000)) 95 | 96 | echo "FIRST:" 97 | echo "${FIRST}" 98 | echo "------" 99 | 100 | test -z "${FIRST}" && echo $"" > "${JS_FILE}" 101 | FIRST="false" 102 | 103 | echo "ReadiumSDK.READIUM_${TARGET_PREFIX}_sha = '${GIT_SHA}';" >> "${JS_FILE}" 104 | echo "ReadiumSDK.READIUM_${TARGET_PREFIX}_tag = '${GIT_TAG}';" >> "${JS_FILE}" 105 | echo "ReadiumSDK.READIUM_${TARGET_PREFIX}_clean = ${GIT_CLEAN};" >> "${JS_FILE}" 106 | 107 | echo "ReadiumSDK.READIUM_${TARGET_PREFIX}_version = '${GIT_VERSION}';" >> "${JS_FILE}" 108 | echo "ReadiumSDK.READIUM_${TARGET_PREFIX}_branch = '${GIT_BRANCH}';" >> "${JS_FILE}" 109 | echo "ReadiumSDK.READIUM_${TARGET_PREFIX}_release = ${GIT_RELEASE};" >> "${JS_FILE}" 110 | echo "ReadiumSDK.READIUM_${TARGET_PREFIX}_timestamp = ${GIT_TIMESTAMP};" >> "${JS_FILE}" 111 | } 112 | 113 | 114 | 115 | GitDo "${pwd}" "" "" "iOS" 116 | 117 | GitDo "${pwd}" "/" "readium-sdk" "SDK" 118 | 119 | GitDo "${pwd}" "/Resources/" "readium-shared-js" "SHARED_JS" 120 | 121 | 122 | 123 | READIUM_dateTimeString=`date` 124 | echo "ReadiumSDK.READIUM_dateTimeString = '${READIUM_dateTimeString}';" >> "${JS_FILE}" 125 | 126 | 127 | cat ${JS_FILE} 128 | 129 | cd "${pwd}" 130 | 131 | echo "###########################################" 132 | echo "###########################################" -------------------------------------------------------------------------------- /Resources/host_app_feedback.js: -------------------------------------------------------------------------------- 1 | // LauncheriOS 2 | // 3 | // Created by Boris Schneiderman. 4 | // Copyright (c) 2014 Readium Foundation and/or its licensees. All rights reserved. 5 | // 6 | // Redistribution and use in source and binary forms, with or without modification, 7 | // are permitted provided that the following conditions are met: 8 | // 1. Redistributions of source code must retain the above copyright notice, this 9 | // list of conditions and the following disclaimer. 10 | // 2. Redistributions in binary form must reproduce the above copyright notice, 11 | // this list of conditions and the following disclaimer in the documentation and/or 12 | // other materials provided with the distribution. 13 | // 3. Neither the name of the organization nor the names of its contributors may be 14 | // used to endorse or promote products derived from this software without specific 15 | // prior written permission. 16 | // 17 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 18 | // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 19 | // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20 | // IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 21 | // INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 22 | // BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 24 | // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 25 | // OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 26 | // OF THE POSSIBILITY OF SUCH DAMAGE. 27 | 28 | $(document).ready(function () 29 | { 30 | console.log("DOM READY"); 31 | 32 | require(["readium_shared_js/globalsSetup"], function () 33 | { 34 | console.log("globalsSetup READY"); 35 | 36 | require(['readium_shared_js/views/reader_view'], function (ReaderView) 37 | { 38 | console.log("reader_view READY"); 39 | 40 | this.useWKWebView = false; 41 | 42 | ReadiumSDK.HostAppFeedback = function () { 43 | 44 | var initNavigatorEpubReadingSystem = function () { 45 | 46 | // Adjust to taste (application/vendor -level metadata): 47 | window.navigator.epubReadingSystem.name = "Readium SDKLauncher-iOS"; 48 | window.navigator.epubReadingSystem.version = "1.0.0"; 49 | 50 | // Readium "internal" version: 51 | ReadiumSDK.READIUM_version = "1.0.0"; 52 | 53 | // Do not edit the following lines! (low-level metadata) 54 | // The templated values ("ReadiumSDK.READIUM_"-prefixed values) are auto-generated by the build script, 55 | // see the "epubReadingSystem.js" file. 56 | 57 | window.navigator.epubReadingSystem.readium = {}; 58 | window.navigator.epubReadingSystem.readium.buildInfo = {}; 59 | 60 | window.navigator.epubReadingSystem.readium.buildInfo.dateTime = ReadiumSDK.READIUM_dateTimeString; 61 | //new Date(timestamp).toString(); 62 | 63 | window.navigator.epubReadingSystem.readium.buildInfo.version = ReadiumSDK.READIUM_version; 64 | 65 | window.navigator.epubReadingSystem.readium.buildInfo.gitRepositories = []; 66 | 67 | var repo1 = {}; 68 | repo1.name = "SDKLauncher-iOS"; 69 | repo1.sha = ReadiumSDK.READIUM_iOS_sha; 70 | repo1.tag = ReadiumSDK.READIUM_iOS_tag; 71 | repo1.clean = ReadiumSDK.READIUM_iOS_clean; 72 | 73 | repo1.version = ReadiumSDK.READIUM_iOS_version; 74 | repo1.branch = ReadiumSDK.READIUM_iOS_branch; 75 | repo1.release = ReadiumSDK.READIUM_iOS_release; 76 | repo1.timestamp = ReadiumSDK.READIUM_iOS_timestamp; 77 | 78 | repo1.url = "https://github.com/readium/" + repo1.name + "/tree/" + repo1.sha; 79 | window.navigator.epubReadingSystem.readium.buildInfo.gitRepositories.push(repo1); 80 | 81 | var repo2 = {}; 82 | repo2.name = "readium-sdk"; 83 | repo2.sha = ReadiumSDK.READIUM_SDK_sha; 84 | repo2.tag = ReadiumSDK.READIUM_SDK_tag; 85 | repo2.clean = ReadiumSDK.READIUM_SDK_clean; 86 | 87 | repo2.version = ReadiumSDK.READIUM_SDK_version; 88 | repo2.branch = ReadiumSDK.READIUM_SDK_branch; 89 | repo2.release = ReadiumSDK.READIUM_SDK_release; 90 | repo2.timestamp = ReadiumSDK.READIUM_SDK_timestamp; 91 | 92 | repo2.url = "https://github.com/readium/" + repo2.name + "/tree/" + repo2.sha; 93 | window.navigator.epubReadingSystem.readium.buildInfo.gitRepositories.push(repo2); 94 | 95 | var repo3 = {}; 96 | repo3.name = "readium-shared-js"; 97 | repo3.sha = ReadiumSDK.READIUM_SHARED_JS_sha; 98 | repo3.tag = ReadiumSDK.READIUM_SHARED_JS_tag; 99 | repo3.clean = ReadiumSDK.READIUM_SHARED_JS_clean; 100 | 101 | repo3.version = ReadiumSDK.READIUM_SHARED_JS_version; 102 | repo3.branch = ReadiumSDK.READIUM_SHARED_JS_branch; 103 | repo3.release = ReadiumSDK.READIUM_SHARED_JS_release; 104 | repo3.timestamp = ReadiumSDK.READIUM_SHARED_JS_timestamp; 105 | 106 | repo3.url = "https://github.com/readium/" + repo3.name + "/tree/" + repo3.sha; 107 | window.navigator.epubReadingSystem.readium.buildInfo.gitRepositories.push(repo3); 108 | 109 | // Debug check: 110 | //console.debug(JSON.stringify(window.navigator.epubReadingSystem, undefined, 2)); 111 | }; 112 | 113 | ReadiumSDK.on(ReadiumSDK.Events.READER_INITIALIZED, function () { 114 | if (window.webkit != null && 115 | window.webkit.messageHandlers != null && 116 | window.webkit.messageHandlers.readium != null) { 117 | // The presence of a "readium" webkit message handler means that WKWebView is in use. 118 | this.useWKWebView = true; 119 | } 120 | 121 | initNavigatorEpubReadingSystem(); 122 | 123 | ReadiumSDK.reader.on(ReadiumSDK.Events.PAGINATION_CHANGED, this.onPaginationChanged, this); 124 | ReadiumSDK.reader.on(ReadiumSDK.Events.SETTINGS_APPLIED, this.onSettingsApplied, this); 125 | ReadiumSDK.reader.on(ReadiumSDK.Events.MEDIA_OVERLAY_STATUS_CHANGED, this.onMediaOverlayStatusChanged, this); 126 | ReadiumSDK.reader.on(ReadiumSDK.Events.MEDIA_OVERLAY_TTS_SPEAK, this.onMediaOverlayTTSSpeak, this); 127 | ReadiumSDK.reader.on(ReadiumSDK.Events.MEDIA_OVERLAY_TTS_STOP, this.onMediaOverlayTTSStop, this); 128 | 129 | if (this.useWKWebView) { 130 | window.webkit.messageHandlers.readium.postMessage(['readerDidInitialize']); 131 | } 132 | else { 133 | window.location.href = "epubobjc:readerDidInitialize"; 134 | } 135 | }, this); 136 | 137 | this.onPaginationChanged = function (pageChangeData) { 138 | pageChangeData.paginationInfo.canGoLeft_ = pageChangeData.paginationInfo.canGoLeft(); 139 | pageChangeData.paginationInfo.canGoRight_ = pageChangeData.paginationInfo.canGoRight(); 140 | var payload = JSON.stringify(pageChangeData.paginationInfo); 141 | 142 | if (this.useWKWebView) { 143 | window.webkit.messageHandlers.readium.postMessage(['pageDidChange', payload]); 144 | } 145 | else { 146 | window.location.href = "epubobjc:pageDidChange?q=" + encodeURIComponent(payload); 147 | } 148 | }; 149 | 150 | this.onSettingsApplied = function () { 151 | if (this.useWKWebView) { 152 | window.webkit.messageHandlers.readium.postMessage(['settingsDidApply']); 153 | } 154 | else { 155 | window.location.href = "epubobjc:settingsDidApply"; 156 | } 157 | }; 158 | 159 | this.onMediaOverlayStatusChanged = function (status) { 160 | var payload = JSON.stringify(status); 161 | 162 | if (this.useWKWebView) { 163 | window.webkit.messageHandlers.readium.postMessage(['mediaOverlayStatusDidChange', payload]); 164 | } 165 | else { 166 | window.location.href = "epubobjc:mediaOverlayStatusDidChange?q=" + encodeURIComponent(payload); 167 | } 168 | }; 169 | 170 | this.onMediaOverlayTTSSpeak = function (tts) { 171 | var payload = JSON.stringify(tts); 172 | 173 | if (this.useWKWebView) { 174 | window.webkit.messageHandlers.readium.postMessage(['mediaOverlayTTSDoSpeak', payload]); 175 | } 176 | else { 177 | window.location.href = "epubobjc:mediaOverlayTTSDoSpeak?q=" + encodeURIComponent(payload); 178 | } 179 | }; 180 | 181 | this.onMediaOverlayTTSStop = function () { 182 | if (this.useWKWebView) { 183 | window.webkit.messageHandlers.readium.postMessage(['mediaOverlayTTSDoStop']); 184 | } 185 | else { 186 | window.location.href = "epubobjc:mediaOverlayTTSDoStop"; 187 | } 188 | }; 189 | 190 | }(); //ReadiumSDK.HostAppFeedback = function () { 191 | 192 | 193 | var opts = { 194 | needsFixedLayoutScalerWorkAround: true, 195 | el: "#viewport", 196 | annotationCSSUrl: '/readium_Annotations.css' //prefix + '/css/annotations.css' 197 | }; 198 | 199 | ReadiumSDK.on(ReadiumSDK.Events.PLUGINS_LOADED, function(reader) 200 | { 201 | // readium built-in (should have been require()'d outside this scope) 202 | console.log(reader.plugins.highlights); 203 | 204 | if (reader.plugins.highlights) { 205 | reader.plugins.highlights.initialize({annotationCSSUrl: opts.annotationCSSUrl}); 206 | 207 | reader.plugins.highlights.on("annotationClicked", function(type, idref, cfi, id) 208 | { 209 | console.log("ANNOTATION CLICK: " + id); 210 | reader.plugins.highlights.removeHighlight(id); 211 | }); 212 | 213 | reader.plugins.highlights.on("textSelectionEvent", function() 214 | { 215 | console.log("ANNOTATION SELECT"); 216 | reader.plugins.highlights.addSelectionHighlight(Math.floor((Math.random()*1000000)), "highlight"); 217 | }); 218 | } 219 | 220 | // external (require()'d via Dependency Injection, see examplePluginConfig function parameter passed above) 221 | console.log(reader.plugins.example); 222 | 223 | }); //ReadiumSDK.on(ReadiumSDK.Events.PLUGINS_LOADED, function(reader) 224 | 225 | //var prefix = (self.location && self.location.origin && self.location.pathname) ? (self.location.origin + self.location.pathname + "/..") : ""; 226 | 227 | ReadiumSDK.reader = new ReaderView(opts); 228 | 229 | console.log("DONE READER"); 230 | 231 | //Globals.emit(Globals.Events.READER_INITIALIZED, ReadiumSDK.reader); 232 | ReadiumSDK.emit(ReadiumSDK.Events.READER_INITIALIZED, ReadiumSDK.reader); 233 | 234 | }); //require(['readium_shared_js/views/reader_view'], function (ReaderView) 235 | 236 | }); //require(["readium_shared_js/globalsSetup"], function () 237 | 238 | }); //$(document).ready(function () 239 | -------------------------------------------------------------------------------- /Resources/moby-dick-20120118.epub: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/readium/SDKLauncher-iOS/3d1fceb3ff096370d9bc7df4a874ac9e4e83db90/Resources/moby-dick-20120118.epub -------------------------------------------------------------------------------- /Resources/page-blanche-20130322.epub: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/readium/SDKLauncher-iOS/3d1fceb3ff096370d9bc7df4a874ac9e4e83db90/Resources/page-blanche-20130322.epub -------------------------------------------------------------------------------- /Resources/reader.css: -------------------------------------------------------------------------------- 1 | html { 2 | height: 100%; 3 | margin: 0; 4 | } 5 | 6 | body { 7 | height: 100%; 8 | width: 100%; 9 | margin: 0; 10 | padding: 20px; 11 | position: absolute; 12 | overflow: hidden; 13 | box-sizing:border-box; 14 | -moz-box-sizing:border-box; /* Firefox */ 15 | -webkit-box-sizing:border-box; /* Safari */ 16 | } 17 | 18 | #viewport_reflowable { 19 | height: 100%; 20 | width: 100%; 21 | margin: 0; 22 | padding: 0; 23 | opacity: 1; 24 | visibility: visible; 25 | overflow: hidden; 26 | } 27 | 28 | #viewport_fixed { 29 | position: absolute; 30 | left: 10px; 31 | right: 10px; 32 | top: 10px; 33 | bottom: 10px; 34 | opacity: 1; 35 | visibility: visible; 36 | overflow: hidden; 37 | } 38 | 39 | iframe { 40 | border-width: 0; 41 | } 42 | 43 | .fixed_iframe { 44 | width: 100%; 45 | height: 100%; 46 | } 47 | 48 | .left_page { 49 | 50 | left: 0; 51 | width: 50%; 52 | height: 100%; 53 | } 54 | 55 | .right_page { 56 | left: 50%; 57 | width: 50%; 58 | height: 100%; 59 | } 60 | 61 | .center_page { 62 | left: 0; 63 | width: 100%; 64 | height: 100%; 65 | } 66 | 67 | .fixed-page-wrap { 68 | 69 | position: absolute; 70 | } 71 | 72 | -------------------------------------------------------------------------------- /Resources/reader.html: -------------------------------------------------------------------------------- 1 | 27 | 28 | 29 | 30 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 |
52 | 53 | 54 | -------------------------------------------------------------------------------- /Resources/reader_RequireJS-multiple-bundles.html: -------------------------------------------------------------------------------- 1 | 27 | 28 | 29 | 30 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 |
84 | 85 | 86 | -------------------------------------------------------------------------------- /Resources/reader_RequireJS-no-optimize.html: -------------------------------------------------------------------------------- 1 | 27 | 28 | 29 | 30 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 |
61 | 62 | 63 | -------------------------------------------------------------------------------- /Resources/reader_RequireJS-single-bundle.html: -------------------------------------------------------------------------------- 1 | 27 | 28 | 29 | 30 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 |
52 | 53 | 54 | -------------------------------------------------------------------------------- /Resources/wasteland-20120118.epub: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/readium/SDKLauncher-iOS/3d1fceb3ff096370d9bc7df4a874ac9e4e83db90/Resources/wasteland-20120118.epub -------------------------------------------------------------------------------- /SDKLauncher-iOS-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | Readium 9 | CFBundleDocumentTypes 10 | 11 | 12 | CFBundleTypeName 13 | EPUB 14 | LSHandlerRank 15 | Alternate 16 | LSItemContentTypes 17 | 18 | org.idpf.epub-container 19 | 20 | 21 | 22 | CFBundleExecutable 23 | ${EXECUTABLE_NAME} 24 | CFBundleIcons 25 | 26 | CFBundlePrimaryIcon 27 | 28 | CFBundleIconFiles 29 | 30 | Icon-29 31 | Icon-40 32 | Icon-50 33 | Icon-57 34 | Icon-60 35 | Icon-72 36 | Icon-76 37 | 38 | UIPrerenderedIcon 39 | 40 | 41 | 42 | CFBundleIdentifier 43 | $(PRODUCT_BUNDLE_IDENTIFIER) 44 | CFBundleInfoDictionaryVersion 45 | 6.0 46 | CFBundleName 47 | ${PRODUCT_NAME} 48 | CFBundlePackageType 49 | APPL 50 | CFBundleShortVersionString 51 | 1 52 | CFBundleSignature 53 | ???? 54 | CFBundleVersion 55 | 0.30.0 56 | LSRequiresIPhoneOS 57 | 58 | NSAppTransportSecurity 59 | 60 | NSAllowsArbitraryLoads 61 | 62 | 63 | UIFileSharingEnabled 64 | 65 | UIRequiredDeviceCapabilities 66 | 67 | armv7 68 | 69 | UISupportedInterfaceOrientations 70 | 71 | UIInterfaceOrientationPortrait 72 | UIInterfaceOrientationLandscapeLeft 73 | UIInterfaceOrientationLandscapeRight 74 | 75 | UISupportedInterfaceOrientations~ipad 76 | 77 | UIInterfaceOrientationPortrait 78 | UIInterfaceOrientationPortraitUpsideDown 79 | UIInterfaceOrientationLandscapeLeft 80 | UIInterfaceOrientationLandscapeRight 81 | 82 | 83 | 84 | -------------------------------------------------------------------------------- /SDKLauncher-iOS-Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header for all source files of the 'SDKLauncher-iOS' target in the 'SDKLauncher-iOS' 3 | // project. 4 | // 5 | 6 | #import 7 | 8 | #ifndef __IPHONE_3_0 9 | #warning "This project uses features only available in iOS SDK 3.0 and later." 10 | #endif 11 | 12 | #ifdef __OBJC__ 13 | #import 14 | #import 15 | #import "LocStr.h" 16 | 17 | #define IS_IPAD (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) 18 | #define SCREEN_SIZE ([UIScreen mainScreen].bounds.size) 19 | #endif 20 | -------------------------------------------------------------------------------- /build.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | Cleaned ${xcworkspace} ! 36 | 37 | 38 | -------------------------------------------------------------------------------- /license.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2014 Readium Foundation and/or its licensees. All rights reserved. 2 | 3 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 4 | 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 5 | 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 6 | 3. Neither the name of the organization nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. 7 | 8 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 9 | --------------------------------------------------------------------------------