Mhurd has uploaded a new change for review.
https://gerrit.wikimedia.org/r/150964
Change subject: References panel now appears on bottom of screen.
......................................................................
References panel now appears on bottom of screen.
Change-Id: Ie3ad35d6065c874eca0d7289cf190bc3e2bc8156
---
M Wikipedia.xcodeproj/project.pbxproj
M wikipedia/Base.lproj/Main_iPhone.storyboard
A wikipedia/View Controllers/References/ReferenceGradientView.h
A wikipedia/View Controllers/References/ReferenceGradientView.m
A wikipedia/View Controllers/References/ReferenceVC.h
A wikipedia/View Controllers/References/ReferenceVC.m
A wikipedia/View Controllers/References/ReferencesVC.h
A wikipedia/View Controllers/References/ReferencesVC.m
M wikipedia/View Controllers/TableOfContents/TOCViewController.m
M wikipedia/View Controllers/WebView/WebViewController.h
M wikipedia/View Controllers/WebView/WebViewController.m
M wikipedia/assets/index.html
M www/index.html
13 files changed, 1,034 insertions(+), 7 deletions(-)
git pull ssh://gerrit.wikimedia.org:29418/apps/ios/wikipedia
refs/changes/64/150964/1
diff --git a/Wikipedia.xcodeproj/project.pbxproj
b/Wikipedia.xcodeproj/project.pbxproj
index 4a0c454..fed55a2 100644
--- a/Wikipedia.xcodeproj/project.pbxproj
+++ b/Wikipedia.xcodeproj/project.pbxproj
@@ -82,6 +82,7 @@
047E74141860509000916964 /* SavedPagesResultPrototypeView.xib
in Resources */ = {isa = PBXBuildFile; fileRef = 047E74131860509000916964 /*
SavedPagesResultPrototypeView.xib */; };
047ED63918C13E4900442BE3 /* PreviewWebView.m in Sources */ =
{isa = PBXBuildFile; fileRef = 047ED63818C13E4900442BE3 /* PreviewWebView.m */;
};
047FF5471889078C009DB293 /* Image+Convenience.m in Sources */ =
{isa = PBXBuildFile; fileRef = 047FF5461889078C009DB293 /* Image+Convenience.m
*/; };
+ 04821CD119895EDC007558F6 /* ReferenceGradientView.m in Sources
*/ = {isa = PBXBuildFile; fileRef = 04821CD019895EDC007558F6 /*
ReferenceGradientView.m */; };
048A26771906268100395F53 /* PaddedLabel.m in Sources */ = {isa
= PBXBuildFile; fileRef = 048A26761906268100395F53 /* PaddedLabel.m */; };
0493C2CC1952373100EBB973 /* CoreDataHousekeeping.m in Sources
*/ = {isa = PBXBuildFile; fileRef = 0493C2CB1952373100EBB973 /*
CoreDataHousekeeping.m */; };
0493C2D419526A0100EBB973 /* WikiFont-Glyphs.ttf in Resources */
= {isa = PBXBuildFile; fileRef = 0493C2D319526A0100EBB973 /*
WikiFont-Glyphs.ttf */; };
@@ -122,6 +123,8 @@
04C91CEF195520990035ED1B /* [email protected] in
Resources */ = {isa = PBXBuildFile; fileRef = 04C91CED195520990035ED1B /*
[email protected] */; };
04C91CF219554B310035ED1B /* logo-onboarding.png in Resources */
= {isa = PBXBuildFile; fileRef = 04C91CF019554B310035ED1B /*
logo-onboarding.png */; };
04C91CF319554B310035ED1B /* [email protected] in Resources
*/ = {isa = PBXBuildFile; fileRef = 04C91CF119554B310035ED1B /*
[email protected] */; };
+ 04CCA0C01983086D000E982A /* ReferencesVC.m in Sources */ = {isa
= PBXBuildFile; fileRef = 04CCA0BF1983086D000E982A /* ReferencesVC.m */; };
+ 04CCA0C319830A44000E982A /* ReferenceVC.m in Sources */ = {isa
= PBXBuildFile; fileRef = 04CCA0C219830A44000E982A /* ReferenceVC.m */; };
04CCCFEE1935093A00E3F60C /* SecondaryMenuRowView.m in Sources
*/ = {isa = PBXBuildFile; fileRef = 04CCCFEA1935093A00E3F60C /*
SecondaryMenuRowView.m */; };
04CCCFEF1935093A00E3F60C /* SecondaryMenuRowView.xib in
Resources */ = {isa = PBXBuildFile; fileRef = 04CCCFEB1935093A00E3F60C /*
SecondaryMenuRowView.xib */; };
04CCCFF01935093A00E3F60C /* SecondaryMenuViewController.m in
Sources */ = {isa = PBXBuildFile; fileRef = 04CCCFED1935093A00E3F60C /*
SecondaryMenuViewController.m */; };
@@ -330,6 +333,8 @@
047ED63818C13E4900442BE3 /* PreviewWebView.m */ = {isa =
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path
= PreviewWebView.m; sourceTree = "<group>"; };
047FF5451889078C009DB293 /* Image+Convenience.h */ = {isa =
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path =
"Image+Convenience.h"; sourceTree = "<group>"; };
047FF5461889078C009DB293 /* Image+Convenience.m */ = {isa =
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path
= "Image+Convenience.m"; sourceTree = "<group>"; };
+ 04821CCF19895EDC007558F6 /* ReferenceGradientView.h */ = {isa =
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path =
ReferenceGradientView.h; sourceTree = "<group>"; };
+ 04821CD019895EDC007558F6 /* ReferenceGradientView.m */ = {isa =
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path
= ReferenceGradientView.m; sourceTree = "<group>"; };
048A26751906268100395F53 /* PaddedLabel.h */ = {isa =
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path =
PaddedLabel.h; sourceTree = "<group>"; };
048A26761906268100395F53 /* PaddedLabel.m */ = {isa =
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc;
lineEnding = 0; path = PaddedLabel.m; sourceTree = "<group>";
xcLanguageSpecificationIdentifier = xcode.lang.objc; };
0493C2CA1952373100EBB973 /* CoreDataHousekeeping.h */ = {isa =
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path =
CoreDataHousekeeping.h; sourceTree = "<group>"; };
@@ -406,6 +411,10 @@
04C91CED195520990035ED1B /* [email protected] */
= {isa = PBXFileReference; lastKnownFileType = image.png; path =
"[email protected]"; sourceTree = "<group>"; };
04C91CF019554B310035ED1B /* logo-onboarding.png */ = {isa =
PBXFileReference; lastKnownFileType = image.png; path = "logo-onboarding.png";
sourceTree = "<group>"; };
04C91CF119554B310035ED1B /* [email protected] */ = {isa =
PBXFileReference; lastKnownFileType = image.png; path =
"[email protected]"; sourceTree = "<group>"; };
+ 04CCA0BE1983086D000E982A /* ReferencesVC.h */ = {isa =
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path =
ReferencesVC.h; sourceTree = "<group>"; };
+ 04CCA0BF1983086D000E982A /* ReferencesVC.m */ = {isa =
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path
= ReferencesVC.m; sourceTree = "<group>"; };
+ 04CCA0C119830A44000E982A /* ReferenceVC.h */ = {isa =
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path =
ReferenceVC.h; sourceTree = "<group>"; };
+ 04CCA0C219830A44000E982A /* ReferenceVC.m */ = {isa =
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path
= ReferenceVC.m; sourceTree = "<group>"; };
04CCCFE91935093A00E3F60C /* SecondaryMenuRowView.h */ = {isa =
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path =
SecondaryMenuRowView.h; sourceTree = "<group>"; };
04CCCFEA1935093A00E3F60C /* SecondaryMenuRowView.m */ = {isa =
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path
= SecondaryMenuRowView.m; sourceTree = "<group>"; };
04CCCFEB1935093A00E3F60C /* SecondaryMenuRowView.xib */ = {isa
= PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path =
SecondaryMenuRowView.xib; sourceTree = "<group>"; };
@@ -1134,6 +1143,7 @@
04F27B6D18FE0F2E00EDD838 /* PageHistory */,
04DD89AE18BFE63A00DD5DAD /* Preview */,
D49B2ECF196C684F002F035D /* PullToRefresh */,
+ 04CCA0BD19830837000E982A /* References */,
0412CC5F192536580010E616 /* Root */,
04293002186030B0002A13FC /* SavedPages */,
04292FEE185FBA70002A13FC /* SearchResults */,
@@ -1246,6 +1256,19 @@
04C91CEA195517250035ED1B /*
OnboardingViewController.m */,
);
path = Onboarding;
+ sourceTree = "<group>";
+ };
+ 04CCA0BD19830837000E982A /* References */ = {
+ isa = PBXGroup;
+ children = (
+ 04CCA0BE1983086D000E982A /* ReferencesVC.h */,
+ 04CCA0BF1983086D000E982A /* ReferencesVC.m */,
+ 04CCA0C119830A44000E982A /* ReferenceVC.h */,
+ 04CCA0C219830A44000E982A /* ReferenceVC.m */,
+ 04821CCF19895EDC007558F6 /*
ReferenceGradientView.h */,
+ 04821CD019895EDC007558F6 /*
ReferenceGradientView.m */,
+ );
+ path = References;
sourceTree = "<group>";
};
04CCCFE81935093A00E3F60C /* Secondary */ = {
@@ -1897,6 +1920,7 @@
0429300A18604898002A13FC /*
SavedPagesResultCell.m in Sources */,
04D34DC11863F6B200610A87 /* History.m in
Sources */,
04D34DAF1863D2D600610A87 /* XPathQuery.m in
Sources */,
+ 04821CD119895EDC007558F6 /*
ReferenceGradientView.m in Sources */,
0472BC18193AD88C00C40BDA /*
Section+DisplayHtml.m in Sources */,
047ED63918C13E4900442BE3 /* PreviewWebView.m in
Sources */,
04B6925018E77B2A00F88D8A /*
UIWebView+HideScrollGradient.m in Sources */,
@@ -1906,6 +1930,7 @@
D4B0AE0B19366A2C00F0AC90 /*
ReadingActionFunnel.m in Sources */,
0452C810195D0F03007925A6 /*
UIViewController+ModalPop.m in Sources */,
041C55D21950B27D006CE0EF /*
EditSummaryViewController.m in Sources */,
+ 04CCA0C01983086D000E982A /* ReferencesVC.m in
Sources */,
04C43ABE183442FC006C643B /*
NSRunLoop+TimeOutAndFlag.m in Sources */,
D4B0AE0E19366A5400F0AC90 /* LoginFunnel.m in
Sources */,
043C668A18BE9A8E00580E9B /* PreviewWikiTextOp.m
in Sources */,
@@ -1919,6 +1944,7 @@
0433542218A023FE009305F0 /*
UIViewController+HideKeyboard.m in Sources */,
C958EE3418CE73E600148D13 /*
DownloadTitlesForRandomArticlesOp.m in Sources */,
0452C803195CB216007925A6 /*
UIViewController+ModalsSearch.m in Sources */,
+ 04CCA0C319830A44000E982A /* ReferenceVC.m in
Sources */,
04B91AB718E4D5B200FFAA1C /* TabularScrollView.m
in Sources */,
04C695D218ED213000D9F2DA /*
UIScrollView+NoHorizontalScrolling.m in Sources */,
04F0E2EE186FB2D100468738 /*
TOCSectionCellView.m in Sources */,
diff --git a/wikipedia/Base.lproj/Main_iPhone.storyboard
b/wikipedia/Base.lproj/Main_iPhone.storyboard
index c44bf88..f8853c8 100644
--- a/wikipedia/Base.lproj/Main_iPhone.storyboard
+++ b/wikipedia/Base.lproj/Main_iPhone.storyboard
@@ -134,7 +134,7 @@
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder"
id="I47-Yh-yr4" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
- <point key="canvasLocation" x="-407" y="698"/>
+ <point key="canvasLocation" x="574" y="730"/>
</scene>
<!--Page History View Controller-->
<scene sceneID="nqw-r1-g0T">
@@ -1198,6 +1198,17 @@
<constraint firstItem="SiM-aO-PlN"
firstAttribute="top" secondItem="F4Q-Xc-ImV" secondAttribute="top"
id="vWw-wM-gCP"/>
</constraints>
</view>
+ <containerView clipsSubviews="YES"
clearsContextBeforeDrawing="NO" contentMode="scaleToFill"
translatesAutoresizingMaskIntoConstraints="NO" id="gB8-UC-wuQ"
userLabel="References Container View">
+ <rect key="frame" x="0.0" y="308" width="320"
height="200"/>
+ <autoresizingMask key="autoresizingMask"
flexibleMaxX="YES" flexibleMaxY="YES"/>
+ <color key="backgroundColor" white="1"
alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
+ <constraints>
+ <constraint firstAttribute="height"
constant="200" id="Z6r-VJ-hik"/>
+ </constraints>
+ <connections>
+ <segue destination="1wG-t8-xjS"
kind="embed" identifier="ReferencesVC_embed" id="fwM-jR-p9Z"/>
+ </connections>
+ </containerView>
</subviews>
<color key="backgroundColor" red="1" green="1"
blue="1" alpha="1" colorSpace="calibratedRGB"/>
<constraints>
@@ -1205,9 +1216,12 @@
<constraint firstItem="WeL-Mj-Zsh"
firstAttribute="leading" secondItem="kh9-bI-dsS" secondAttribute="leading"
id="3Zs-jL-a48"/>
<constraint firstItem="WeL-Mj-Zsh"
firstAttribute="trailing" secondItem="F4Q-Xc-ImV" secondAttribute="trailing"
id="J2p-jy-zrW"/>
<constraint firstAttribute="trailing"
secondItem="WeL-Mj-Zsh" secondAttribute="trailing" id="QSr-uN-iN4"/>
+ <constraint firstItem="WeL-Mj-Zsh"
firstAttribute="leading" secondItem="gB8-UC-wuQ" secondAttribute="leading"
id="TPG-uM-6qs"/>
<constraint firstItem="WeL-Mj-Zsh"
firstAttribute="leading" secondItem="F4Q-Xc-ImV" secondAttribute="leading"
id="akc-jF-1Pw"/>
<constraint firstAttribute="bottom"
secondItem="F4Q-Xc-ImV" secondAttribute="bottom" placeholder="YES"
id="bOy-uv-taw"/>
<constraint firstAttribute="bottom"
secondItem="WeL-Mj-Zsh" secondAttribute="bottom" id="myK-xK-1sX"/>
+ <constraint firstItem="gB8-UC-wuQ"
firstAttribute="bottom" secondItem="kh9-bI-dsS" secondAttribute="bottom"
id="nMr-wt-aMC"/>
+ <constraint firstItem="WeL-Mj-Zsh"
firstAttribute="trailing" secondItem="gB8-UC-wuQ" secondAttribute="trailing"
id="sLM-fO-nId"/>
</constraints>
</view>
<extendedEdge key="edgesForExtendedLayout"/>
@@ -1217,6 +1231,9 @@
</navigationItem>
<connections>
<outlet property="bottomBarView"
destination="F4Q-Xc-ImV" id="U8K-lV-PiW"/>
+ <outlet property="referencesContainerView"
destination="gB8-UC-wuQ" id="f7G-jI-SWO"/>
+ <outlet
property="referencesContainerViewBottomConstraint" destination="nMr-wt-aMC"
id="z1X-xR-f8n"/>
+ <outlet
property="referencesContainerViewHeightConstraint" destination="Z6r-VJ-hik"
id="vdX-Ye-y6G"/>
<outlet property="webView" destination="WeL-Mj-Zsh"
id="UAL-nl-cQD"/>
<outlet property="webViewLeftConstraint"
destination="3Zs-jL-a48" id="fnl-sG-tsS"/>
<outlet property="webViewRightConstraint"
destination="QSr-uN-iN4" id="EG4-9F-vyJ"/>
@@ -1423,6 +1440,69 @@
</objects>
<point key="canvasLocation" x="-1137" y="-210"/>
</scene>
+ <!--ReferenceVC-->
+ <scene sceneID="oNi-7F-FeN">
+ <objects>
+ <viewController restorationIdentifier="ReferenceVC"
storyboardIdentifier="ReferenceVC" extendedLayoutIncludesOpaqueBars="YES"
automaticallyAdjustsScrollViewInsets="NO" id="Pxx-VU-xla"
customClass="ReferenceVC" sceneMemberID="viewController">
+ <layoutGuides>
+ <viewControllerLayoutGuide type="top" id="KFQ-nS-ONF"/>
+ <viewControllerLayoutGuide type="bottom"
id="XwI-oB-1rV"/>
+ </layoutGuides>
+ <view key="view" contentMode="scaleToFill" id="rS5-jM-7C5">
+ <rect key="frame" x="0.0" y="0.0" width="320"
height="300"/>
+ <autoresizingMask key="autoresizingMask"
flexibleMaxX="YES" flexibleMaxY="YES"/>
+ <subviews>
+ <webView opaque="NO"
clearsContextBeforeDrawing="NO" contentMode="scaleToFill"
allowsInlineMediaPlayback="NO" mediaPlaybackAllowsAirPlay="NO"
translatesAutoresizingMaskIntoConstraints="NO" id="90R-X9-ZAd">
+ <rect key="frame" x="0.0" y="0.0" width="320"
height="300"/>
+ <autoresizingMask key="autoresizingMask"
flexibleMaxX="YES" flexibleMaxY="YES"/>
+ <color key="backgroundColor" white="0.0"
alpha="1" colorSpace="calibratedWhite"/>
+ <dataDetectorType key="dataDetectorTypes"/>
+ </webView>
+ </subviews>
+ <color key="backgroundColor" white="0.0" alpha="1"
colorSpace="calibratedWhite"/>
+ <constraints>
+ <constraint firstAttribute="trailing"
secondItem="90R-X9-ZAd" secondAttribute="trailing" id="4QL-a7-pAf"/>
+ <constraint firstAttribute="bottom"
secondItem="90R-X9-ZAd" secondAttribute="bottom" id="8uv-Uy-4Ox"/>
+ <constraint firstItem="90R-X9-ZAd"
firstAttribute="leading" secondItem="rS5-jM-7C5" secondAttribute="leading"
id="b3G-88-nvO"/>
+ <constraint firstItem="90R-X9-ZAd"
firstAttribute="top" secondItem="rS5-jM-7C5" secondAttribute="top"
id="jtu-qj-29x"/>
+ </constraints>
+ </view>
+ <nil key="simulatedStatusBarMetrics"/>
+ <nil key="simulatedTopBarMetrics"/>
+ <nil key="simulatedBottomBarMetrics"/>
+ <freeformSimulatedSizeMetrics
key="simulatedDestinationMetrics"/>
+ <size key="freeformSize" width="320" height="300"/>
+ <connections>
+ <outlet property="referenceWebView"
destination="90R-X9-ZAd" id="NWM-sh-DXF"/>
+ </connections>
+ </viewController>
+ <placeholder placeholderIdentifier="IBFirstResponder"
id="zcN-5N-Ydk" userLabel="First Responder" sceneMemberID="firstResponder"/>
+ </objects>
+ <point key="canvasLocation" x="-478" y="955"/>
+ </scene>
+ <!--ReferencesVC-->
+ <scene sceneID="Qi9-my-V1s">
+ <objects>
+ <viewController restorationIdentifier="ReferencesVC"
storyboardIdentifier="ReferencesVC" extendedLayoutIncludesOpaqueBars="YES"
automaticallyAdjustsScrollViewInsets="NO" id="1wG-t8-xjS"
customClass="ReferencesVC" sceneMemberID="viewController">
+ <layoutGuides>
+ <viewControllerLayoutGuide type="top" id="IrU-sf-pxP"/>
+ <viewControllerLayoutGuide type="bottom"
id="atY-QA-Qs8"/>
+ </layoutGuides>
+ <view key="view" contentMode="scaleToFill" id="357-00-U3r">
+ <rect key="frame" x="0.0" y="0.0" width="320"
height="300"/>
+ <autoresizingMask key="autoresizingMask"
flexibleMaxX="YES" flexibleMaxY="YES"/>
+ <color key="backgroundColor" white="0.0" alpha="1"
colorSpace="calibratedWhite"/>
+ </view>
+ <nil key="simulatedStatusBarMetrics"/>
+ <nil key="simulatedTopBarMetrics"/>
+ <nil key="simulatedBottomBarMetrics"/>
+ <freeformSimulatedSizeMetrics
key="simulatedDestinationMetrics"/>
+ <size key="freeformSize" width="320" height="300"/>
+ </viewController>
+ <placeholder placeholderIdentifier="IBFirstResponder"
id="Z8Q-li-V84" userLabel="First Responder" sceneMemberID="firstResponder"/>
+ </objects>
+ <point key="canvasLocation" x="-478" y="559"/>
+ </scene>
<!--Modal Menu And Content View Controller-->
<scene sceneID="pAe-va-e4P">
<objects>
@@ -1626,7 +1706,7 @@
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder"
id="heC-Be-Fgw" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
- <point key="canvasLocation" x="89" y="434"/>
+ <point key="canvasLocation" x="478" y="501"/>
</scene>
<!--Center Nav Controller-->
<scene sceneID="dor-Wk-JQd">
diff --git a/wikipedia/View Controllers/References/ReferenceGradientView.h
b/wikipedia/View Controllers/References/ReferenceGradientView.h
new file mode 100644
index 0000000..bfb2037
--- /dev/null
+++ b/wikipedia/View Controllers/References/ReferenceGradientView.h
@@ -0,0 +1,8 @@
+// Created by Monte Hurd on 7/30/14.
+// Copyright (c) 2014 Wikimedia Foundation. Provided under MIT-style license;
please copy and modify!
+
+#import <UIKit/UIKit.h>
+
+@interface ReferenceGradientView : UIView
+
+@end
diff --git a/wikipedia/View Controllers/References/ReferenceGradientView.m
b/wikipedia/View Controllers/References/ReferenceGradientView.m
new file mode 100644
index 0000000..165a22a
--- /dev/null
+++ b/wikipedia/View Controllers/References/ReferenceGradientView.m
@@ -0,0 +1,60 @@
+// Created by Monte Hurd on 7/30/14.
+// Copyright (c) 2014 Wikimedia Foundation. Provided under MIT-style license;
please copy and modify!
+
+#import "ReferenceGradientView.h"
+
+@implementation ReferenceGradientView
+
+- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event {
+ // Allow side-swipes to fall through to the references web view, but not
+ // if a sub view with userInteractionEnabled YES was tapped.
+ // See: http://stackoverflow.com/a/12355957
+ for (UIView *view in self.subviews) {
+ if (view.userInteractionEnabled) {
+ if (CGRectContainsPoint(view.frame, point)) return YES;
+ }
+ }
+ return NO;
+}
+
+- (void)drawRect:(CGRect)rect
+{
+ [super drawRect:rect];
+
+ CGContextRef ctx = UIGraphicsGetCurrentContext();
+
+ CGFloat topHalfAlpha = 0.88;
+
+ // Make the gradient begin just below the vertical center.
+ CGFloat gradientTop = CGRectGetMidY(rect) + 10;
+
+ // Draw opaque black in top half of rect.
+ CGRect topHalfRect = CGRectMake(rect.origin.x, rect.origin.y,
rect.size.width, gradientTop);
+ CGContextSetRGBFillColor(ctx, 0.0, 0.0, 0.0, topHalfAlpha);
+ CGContextSetRGBStrokeColor(ctx, 0.0, 0.0, 0.0, topHalfAlpha);
+ CGContextFillRect(ctx, topHalfRect);
+
+ // Draw black to transparent gradient from middle to bottom of rect.
+ // Gradient drawing based on: http://stackoverflow.com/a/422208
+ CGGradientRef gradient;
+ CGColorSpaceRef rgbSpace;
+ size_t locationCount = 2;
+ CGFloat locations[2] = { 0.0, 1.0 };
+ CGFloat colorComponents[8] = {
+ 0.0, 0.0, 0.0, topHalfAlpha, // starting color
+ 0.0, 0.0, 0.0, 0.0 // ending color
+ };
+
+ rgbSpace = CGColorSpaceCreateDeviceRGB();
+ gradient = CGGradientCreateWithColorComponents(rgbSpace, colorComponents,
locations, locationCount);
+
+ //CGPoint topCenter = CGPointMake(CGRectGetMidX(currentBounds), 0.0f);
+ CGPoint midCenter = CGPointMake(CGRectGetMidX(rect), gradientTop);
+ CGPoint bottomCenter = CGPointMake(CGRectGetMidX(rect),
CGRectGetMaxY(rect));
+ CGContextDrawLinearGradient(ctx, gradient, midCenter, bottomCenter, 0);
+
+ CGGradientRelease(gradient);
+ CGColorSpaceRelease(rgbSpace);
+}
+
+@end
diff --git a/wikipedia/View Controllers/References/ReferenceVC.h
b/wikipedia/View Controllers/References/ReferenceVC.h
new file mode 100644
index 0000000..8469104
--- /dev/null
+++ b/wikipedia/View Controllers/References/ReferenceVC.h
@@ -0,0 +1,18 @@
+// Created by Monte Hurd on 7/25/14.
+// Copyright (c) 2014 Wikimedia Foundation. Provided under MIT-style license;
please copy and modify!
+
+#import <UIKit/UIKit.h>
+
+@class WebViewController;
+@interface ReferenceVC : UIViewController <UIWebViewDelegate>
+
+@property (assign, nonatomic) NSInteger index;
+
+@property (strong, nonatomic) NSString *html;
+
+@property (strong, nonatomic) NSString *linkId;
+@property (strong, nonatomic) NSString *linkText;
+
+@property (weak, nonatomic) WebViewController *webVC;
+
+@end
diff --git a/wikipedia/View Controllers/References/ReferenceVC.m
b/wikipedia/View Controllers/References/ReferenceVC.m
new file mode 100644
index 0000000..52c36ac
--- /dev/null
+++ b/wikipedia/View Controllers/References/ReferenceVC.m
@@ -0,0 +1,171 @@
+// Created by Monte Hurd on 7/25/14.
+// Copyright (c) 2014 Wikimedia Foundation. Provided under MIT-style license;
please copy and modify!
+
+#import "ReferenceVC.h"
+#import "WebViewController.h"
+#import "SessionSingleton.h"
+#import "MWLanguageInfo.h"
+#import "WikipediaAppUtils.h"
+
+#define REFERENCE_LINK_COLOR @"#2b6fb2"
+
+@interface ReferenceVC ()
+
+@property (strong, nonatomic) IBOutlet UIWebView *referenceWebView;
+
+@end
+
+@implementation ReferenceVC
+
+- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest
*)request navigationType:(UIWebViewNavigationType)navigationType
+{
+ //NSLog(@"request = %@ \ntype = %d", request, navigationType);
+ switch (navigationType) {
+ case UIWebViewNavigationTypeOther:
+ // YES allows the reference html to actually be
loaded/displayed.
+ return YES;
+ break;
+ case UIWebViewNavigationTypeLinkClicked: {
+ NSURL *requestURL = [request URL];
+
+// Test wiki link:
+//requestURL = [NSURL URLWithString:@"/wiki/toast"];
+
+ NSString *scheme = [requestURL scheme];
+
+ // Open external link in Safari.
+ if (
+ [scheme isEqualToString:@"http"]
+ ||
+ [scheme isEqualToString:@"https"]
+ ||
+ [scheme isEqualToString:@"mailto"]
+ ){
+ [[UIApplication sharedApplication] openURL:requestURL];
+
+ // Or open wiki link in the WebViewController's web view.
+ }else if ([requestURL.path hasPrefix:@"/wiki/"]) {
+
+ NSString *href = requestURL.path;
+ NSString *encodedTitle = [href
substringWithRange:NSMakeRange(6, href.length - 6)];
+ NSString *title = [encodedTitle
stringByRemovingPercentEncoding];
+ MWPageTitle *pageTitle = [MWPageTitle
titleWithString:title];
+ [self.webVC navigateToPage: pageTitle
+ domain: [SessionSingleton
sharedInstance].currentArticleDomain
+ discoveryMethod: DISCOVERY_METHOD_LINK
+ invalidatingCache: NO];
+ [self.webVC referencesHide];
+ }
+
+ return NO;
+ }
+ default:
+ return NO;
+ break;
+ }
+}
+
+- (void)viewDidLoad
+{
+ [super viewDidLoad];
+ // Do any additional setup after loading the view.
+
+ // Prevent this web view from blocking the article web view from scrolling
to top
+ // when title bar tapped. (Only one scroll view can have scrollsToTop set
to YES for
+ // the title bar tap to cause scroll-to-top.)
+ self.referenceWebView.scrollView.scrollsToTop = NO;
+ self.referenceWebView.delegate = self;
+
+ NSString *domain = [SessionSingleton sharedInstance].currentArticleDomain;
+ MWLanguageInfo *languageInfo = [MWLanguageInfo languageInfoForCode:domain];
+ NSString *baseUrl = [NSString
stringWithFormat:@"https://%@.wikipedia.org/", languageInfo.code];
+
+ NSString *html = [NSString stringWithFormat:@"\
+<html>\
+<head>\
+<base href='%@' target='_self'>\
+<style>\
+ *{\
+ color:#999;\
+ font-family:'Helvetica Neue';\
+ font-size:14pt;\
+ font-weight:normal;\
+ line-height:148%%;\
+ font-style:normal;\
+ -webkit-text-size-adjust: none;\
+ -webkit-hyphens: auto;\
+ word-break: break-word;\
+ }\
+ BODY{\
+ padding-left:10;\
+ padding-right:10;\
+ }\
+ A, A *{\
+ color:%@;\
+ text-decoration:none;\
+ }\
+</style>\
+</head>\
+<body style='background-color:black;' lang='%@' dir='%@'>\
+%@ %@\
+</body>\
+</html>\
+", baseUrl, REFERENCE_LINK_COLOR, languageInfo.code, languageInfo.dir,
self.linkText, self.html];
+
+ [self.referenceWebView loadHTMLString:html baseURL:[NSURL
URLWithString:@""]];
+
+ CGFloat topInset = 32;
+
+ CGFloat bottomInset = (NSFoundationVersionNumber >
NSFoundationVersionNumber_iOS_6_1) ? 0 : topInset;
+
+ self.referenceWebView.scrollView.contentInset = UIEdgeInsetsMake(topInset,
0, bottomInset, 0);
+
+ //self.webView.layer.borderColor = [UIColor whiteColor].CGColor;
+ //self.webView.layer.borderWidth = 25;
+
+ //self.view.layer.borderColor = [UIColor whiteColor].CGColor;
+ //self.view.layer.borderWidth = 1;
+}
+
+-(void)viewDidAppear:(BOOL)animated
+{
+ [super viewDidAppear:animated];
+
+ NSString *eval = [NSString stringWithFormat:@"\
+ document.getElementById('%@').oldBackgroundColor =
document.getElementById('%@').style.backgroundColor;\
+ document.getElementById('%@').style.backgroundColor = '#999';\
+ document.getElementById('%@').style.borderRadius = 2;\
+ ", self.linkId, self.linkId, self.linkId, self.linkId];
+
+ [self.webVC.webView stringByEvaluatingJavaScriptFromString:eval];
+}
+
+-(void)viewWillDisappear:(BOOL)animated
+{
+ NSString *eval = [NSString stringWithFormat:@"\
+ document.getElementById('%@').style.backgroundColor =
document.getElementById('%@').oldBackgroundColor;\
+ ", self.linkId, self.linkId];
+
+ [self.webVC.webView stringByEvaluatingJavaScriptFromString:eval];
+
+ [super viewWillDisappear:animated];
+}
+
+- (void)didReceiveMemoryWarning
+{
+ [super didReceiveMemoryWarning];
+ // Dispose of any resources that can be recreated.
+}
+
+/*
+#pragma mark - Navigation
+
+// In a storyboard-based application, you will often want to do a little
preparation before navigation
+- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
+{
+ // Get the new view controller using [segue destinationViewController].
+ // Pass the selected object to the new view controller.
+}
+*/
+
+@end
diff --git a/wikipedia/View Controllers/References/ReferencesVC.h
b/wikipedia/View Controllers/References/ReferencesVC.h
new file mode 100644
index 0000000..b413baa
--- /dev/null
+++ b/wikipedia/View Controllers/References/ReferencesVC.h
@@ -0,0 +1,17 @@
+// Created by Monte Hurd on 7/25/14.
+// Copyright (c) 2014 Wikimedia Foundation. Provided under MIT-style license;
please copy and modify!
+
+#import <UIKit/UIKit.h>
+
+@class WebViewController;
+@interface ReferencesVC : UIViewController <UIPageViewControllerDataSource,
UIPageViewControllerDelegate>
+
+@property (strong, nonatomic) UIPageViewController *pageController;
+
+@property (strong, nonatomic) NSDictionary *payload;
+
+@property (weak, nonatomic) WebViewController *webVC;
+
+-(void)reset;
+
+@end
diff --git a/wikipedia/View Controllers/References/ReferencesVC.m
b/wikipedia/View Controllers/References/ReferencesVC.m
new file mode 100644
index 0000000..e8f251a
--- /dev/null
+++ b/wikipedia/View Controllers/References/ReferencesVC.m
@@ -0,0 +1,521 @@
+// Created by Monte Hurd on 7/25/14.
+// Copyright (c) 2014 Wikimedia Foundation. Provided under MIT-style license;
please copy and modify!
+
+#import "ReferencesVC.h"
+#import "ReferenceVC.h"
+#import "WikiGlyphButton.h"
+#import "WikiGlyphLabel.h"
+#import "WikiGlyph_Chars.h"
+#import "WikiGlyph_Chars_iOS.h"
+#import "WebViewController.h"
+#import "WikipediaAppUtils.h"
+#import "UIView+Debugging.h"
+#import "WMF_Colors.h"
+#import "ReferenceGradientView.h"
+#import "SessionSingleton.h"
+#import "MWLanguageInfo.h"
+#import "UIWebView+ElementLocation.h"
+
+
+
+// TODO:
+// scroll up if link covered by refs panel
+// ask brion where to put "a:hover {text-decoration: none;}"
+
+
+
+
+// Show prev-next buttons instead of page dots if number of refs exceeds this
number.
+#define PAGE_CONTROL_MAX_REFS 10
+#define PAGE_CONTROL_DOT_COLOR 0x2b6fb2
+
+@interface ReferencesVC ()
+
+@property (strong, nonatomic) UIPageControl *topPageControl;
+@property (strong, nonatomic) WikiGlyphButton *xButton;
+
+@property (strong, nonatomic) WikiGlyphButton *nextButton;
+@property (strong, nonatomic) WikiGlyphButton *prevButton;
+
+@property (strong, nonatomic) ReferenceGradientView *topContainerView;
+
+@property (strong, nonatomic) NSArray *refs;
+@property (nonatomic) NSUInteger refsIndex;
+@property (strong, nonatomic) NSArray *linkIds;
+@property (strong, nonatomic) NSArray *linkText;
+
+@end
+
+@implementation ReferencesVC
+
+-(void)reset
+{
+ // Load a fake blank set of data.
+ self.payload = @{
+ @"linkId": @[@"fake_refs_id"],
+ @"linkText": @[@""],
+ @"refs": @[@""],
+ @"refsIndex": @(0)
+ };
+}
+
+- (void)viewDidLoad
+{
+ [super viewDidLoad];
+ // Do any additional setup after loading the view.
+
+ self.refs = @[@""];
+ self.linkIds = @[];
+ self.linkText = @[];
+ self.refsIndex = 0;
+
+ self.view.backgroundColor = [UIColor blackColor];
+
+ [self setupPageController];
+
+ [self setupTopContainer];
+
+ [self setupConstraints];
+
+ //self.view.layer.borderColor = [UIColor redColor].CGColor;
+ //self.view.layer.borderWidth = 10;
+ //[self.view randomlyColorSubviews];
+}
+
+- (void)setupPageController
+{
+ self.pageController =
+ [[UIPageViewController alloc] initWithTransitionStyle:
UIPageViewControllerTransitionStyleScroll
+ navigationOrientation:
UIPageViewControllerNavigationOrientationHorizontal
+ options: nil];
+
+ if(NSFoundationVersionNumber <= NSFoundationVersionNumber_iOS_6_1){
+ // Needed for iOS 6. Otherwise a 20 pixel gap appears above.
+ self.pageController.wantsFullScreenLayout = YES;
+ }
+
+ self.pageController.dataSource = self;
+ self.pageController.delegate = self;
+
+ [self addChildViewController:self.pageController];
+ [self.view addSubview:self.pageController.view];
+ [self.pageController didMoveToParentViewController:self];
+
+ ReferenceVC *initialVC = [self viewControllerAtIndex:0];
+
+ if (initialVC){
+ [self setViewControllers: @[initialVC]
+ direction:
UIPageViewControllerNavigationDirectionForward
+ animated: NO
+ completion: nil];
+ }
+}
+
+- (void)setupTopContainer
+{
+ self.topContainerView = [[ReferenceGradientView alloc] init];
+
+ self.topContainerView.translatesAutoresizingMaskIntoConstraints = NO;
+ self.topContainerView.backgroundColor = [UIColor clearColor];
+ [self.view addSubview:self.topContainerView];
+
+ self.xButton = [[WikiGlyphButton alloc] init];
+ self.xButton.translatesAutoresizingMaskIntoConstraints = NO;
+ [self.xButton.label setWikiText: WIKIGLYPH_X
+ color: [UIColor darkGrayColor]
+ size: 22
+ baselineOffset: 0];
+ self.xButton.label.textAlignment = NSTextAlignmentCenter;
+ self.xButton.userInteractionEnabled = YES;
+ [self.topContainerView addSubview:self.xButton];
+
+ BOOL isRTL = [WikipediaAppUtils isDeviceLanguageRTL];
+
+ self.nextButton = [[WikiGlyphButton alloc] init];
+ self.nextButton.translatesAutoresizingMaskIntoConstraints = NO;
+ [self.nextButton.label setWikiText: isRTL ? IOS_WIKIGLYPH_BACKWARD :
IOS_WIKIGLYPH_FORWARD
+ color: [UIColor darkGrayColor]
+ size: 24
+ baselineOffset: 2.0];
+ self.nextButton.hidden = YES;
+ [self.topContainerView addSubview:self.nextButton];
+
+ self.prevButton = [[WikiGlyphButton alloc] init];
+ self.prevButton.translatesAutoresizingMaskIntoConstraints = NO;
+ [self.prevButton.label setWikiText: isRTL ? IOS_WIKIGLYPH_FORWARD :
IOS_WIKIGLYPH_BACKWARD
+ color: [UIColor darkGrayColor]
+ size: 24
+ baselineOffset: 2.0];
+ self.prevButton.hidden = YES;
+ [self.topContainerView addSubview:self.prevButton];
+
+ UITapGestureRecognizer *prevTap = [[UITapGestureRecognizer alloc]
initWithTarget:self action:@selector(prevButtonTap)];
+ [self.prevButton addGestureRecognizer:prevTap];
+
+ UITapGestureRecognizer *nextTap = [[UITapGestureRecognizer alloc]
initWithTarget:self action:@selector(nextButtonTap)];
+ [self.nextButton addGestureRecognizer:nextTap];
+
+ UITapGestureRecognizer *xTap = [[UITapGestureRecognizer alloc]
initWithTarget:self action:@selector(xButtonTap)];
+ [self.xButton addGestureRecognizer:xTap];
+
+ //self.nextButton.layer.borderWidth = 1;
+ //self.prevButton.layer.borderWidth = 1;
+ //self.nextButton.layer.borderColor = [UIColor whiteColor].CGColor;
+ //self.prevButton.layer.borderColor = [UIColor whiteColor].CGColor;
+
+ //self.xButton.layer.borderWidth = 1;
+ //self.xButton.layer.borderColor = [UIColor whiteColor].CGColor;
+
+ self.topPageControl = [[UIPageControl alloc] init];
+
+ //self.topPageControl.pageIndicatorTintColor = [UIColor redColor];
+ self.topPageControl.currentPageIndicatorTintColor =
UIColorFromRGBWithAlpha(PAGE_CONTROL_DOT_COLOR, 1.0);
+
+ self.topPageControl.translatesAutoresizingMaskIntoConstraints = NO;
+ self.topPageControl.numberOfPages = 0;
+ self.topPageControl.currentPage = 0;
+ self.topPageControl.hidesForSinglePage = YES;
+ [self.topPageControl addTarget:self
action:@selector(topPageControlTapped:)
forControlEvents:UIControlEventValueChanged];
+ [self.topContainerView addSubview:self.topPageControl];
+
+ // For now disable page control interactions. Taps are ok, but
+ // if you try to swipe the page control is doing something goofy
+ // with control events and swipes are sometimes falling through
+ // to the article web view, which causes the WebViewController
+ // to present the TOC.
+ self.topPageControl.userInteractionEnabled = NO;
+
+ //self.topContainerView.layer.borderWidth = 1;
+ //self.topContainerView.layer.borderColor = [UIColor whiteColor].CGColor;
+}
+
+-(void)xButtonTap
+{
+ [self.webVC referencesHide];
+}
+
+-(void)setupConstraints
+{
+ NSDictionary *views = @{
+ @"xButton": self.xButton,
+ @"topPageControl": self.topPageControl,
+ @"topContainerView": self.topContainerView,
+ @"nextButton": self.nextButton,
+ @"prevButton": self.prevButton
+ };
+
+ NSDictionary *metrics = @{
+ @"topItemsHeight": @50,
+ @"vPadding": @7,
+ @"hPadding": @14,
+ @"xWidth": @50
+ };
+
+ [self.topContainerView addConstraints:[NSLayoutConstraint
constraintsWithVisualFormat: @"H:|[xButton(xWidth)]"
+ options: 0
+ metrics:
metrics
+ views:
views]];
+
+ [self.topContainerView addConstraints:[NSLayoutConstraint
constraintsWithVisualFormat: @"H:[topPageControl]-(25)-|"
+ options: 0
+ metrics:
metrics
+ views:
views]];
+
+ [self.topContainerView addConstraints:[NSLayoutConstraint
constraintsWithVisualFormat: @"V:|-(vPadding)-[xButton]-(vPadding)-|"
+ options: 0
+ metrics:
metrics
+ views:
views]];
+
+ [self.topContainerView addConstraints:[NSLayoutConstraint
constraintsWithVisualFormat: @"V:|-(vPadding)-[nextButton]-(vPadding)-|"
+ options: 0
+ metrics:
metrics
+ views:
views]];
+
+ [self.topContainerView addConstraints:[NSLayoutConstraint
constraintsWithVisualFormat: @"V:|-(vPadding)-[prevButton]-(vPadding)-|"
+ options: 0
+ metrics:
metrics
+ views:
views]];
+
+ [self.topContainerView addConstraints:[NSLayoutConstraint
constraintsWithVisualFormat: @"H:[prevButton]-(20)-[nextButton]-(hPadding)-|"
+ options: 0
+ metrics:
metrics
+ views:
views]];
+
+ [self.topContainerView addConstraints:[NSLayoutConstraint
constraintsWithVisualFormat: @"V:|-(vPadding)-[topPageControl]-(vPadding)-|"
+ options: 0
+ metrics:
metrics
+ views:
views]];
+
+ [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:
@"V:|[topContainerView(topItemsHeight)]"
+ options: 0
+ metrics:
metrics
+ views:
views]];
+
+ [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:
@"H:|[topContainerView]|"
+ options: 0
+ metrics:
metrics
+ views:
views]];
+}
+
+-(NSArray *)refs
+{
+ if (!_refs || (_refs.count == 0)) return @[@""];
+ return self.payload[@"refs"];
+}
+
+-(NSUInteger)refsIndex
+{
+ NSNumber *index = self.payload[@"refsIndex"];
+ return index.integerValue;
+}
+
+-(NSArray *)linkIds
+{
+ return self.payload[@"linkId"];
+}
+
+-(NSArray *)linkText
+{
+ return self.payload[@"linkText"];
+}
+
+-(NSDictionary *)reversePayloadArraysIfRTL:(NSDictionary *)payload
+{
+ //NSString *domain = [SessionSingleton
sharedInstance].currentArticleDomain;
+ //MWLanguageInfo *languageInfo = [MWLanguageInfo
languageInfoForCode:domain];
+ BOOL isRTL = [WikipediaAppUtils isDeviceLanguageRTL];
+ if (isRTL) {
+ //if ([languageInfo.dir isEqualToString:@"ltr"]) {
+ NSArray *a = payload[@"linkId"];
+ if (a.count > 0) {
+ NSNumber *n = payload[@"refsIndex"];
+ payload = @{
+ @"linkId": [[payload[@"linkId"]
reverseObjectEnumerator] allObjects],
+ @"linkText": [[payload[@"linkText"]
reverseObjectEnumerator] allObjects],
+ @"refs": [[payload[@"refs"] reverseObjectEnumerator]
allObjects],
+ @"refsIndex": @((a.count-1) - n.integerValue)
+ };
+ }
+ }
+ return payload;
+}
+
+-(void)scrollTappedReferenceUp
+{
+ NSNumber *n = self.payload[@"refsIndex"];
+ if (!n) return;
+ NSArray *a = self.payload[@"linkId"];
+ if (!a) return;
+ NSString *elementId = a[n.integerValue];
+ if (!elementId) return;
+ CGRect r = [self.webVC.webView
getScreenRectForHtmlElementWithId:elementId];
+ if (!CGRectIsNull(r)) {
+ CGPoint p = CGPointMake(
+ self.webVC.webView.scrollView.contentOffset.x,
+ self.webVC.webView.scrollView.contentOffset.y
+ (r.origin.y - 70)
+ );
+ [self.webVC.webView.scrollView setContentOffset:p animated:YES];
+ };
+}
+
+-(void)setPayload:(NSDictionary *)payload
+{
+ payload = [self reversePayloadArraysIfRTL:payload];
+
+ _payload = payload;
+
+ [self scrollTappedReferenceUp];
+
+ BOOL hidePageControl = (self.refs.count > PAGE_CONTROL_MAX_REFS);
+ self.prevButton.hidden = (!hidePageControl) || (self.refs.count < 2);
+ self.nextButton.hidden = (!hidePageControl) || (self.refs.count < 2);
+ // Use alpha - other changes to page control properties apparently cause
it to be
+ // set to be not hidden. This way all that other code can remain as-is.
+ self.topPageControl.alpha = (hidePageControl ? 0.0 : 1.0);
+
+ UIPageViewControllerNavigationDirection dir =
(self.topPageControl.currentPage < self.refsIndex)
+ ?
+ UIPageViewControllerNavigationDirectionForward
+ :
+ UIPageViewControllerNavigationDirectionReverse;
+
+ BOOL shouldAnimate = ((self.refs.count == 1) ? NO: YES);
+
+ if (self.topPageControl.currentPage == self.refsIndex) shouldAnimate = NO;
+
+ [self setViewControllers: @[[self viewControllerAtIndex:self.refsIndex]]
+ direction: dir
+ animated: shouldAnimate
+ completion: nil];
+
+ self.topPageControl.numberOfPages = self.refs.count;
+ self.topPageControl.currentPage = self.refsIndex;
+}
+
+-(void)refViewDidAppear:(NSUInteger)index
+{
+ self.prevButton.enabled = (index <= 0) ? NO : YES;
+ self.nextButton.enabled = (index >= (self.refs.count - 1)) ? NO : YES;
+}
+
+- (void)setViewControllers: (NSArray *)viewControllers
+ direction: (UIPageViewControllerNavigationDirection)direction
+ animated: (BOOL)animated
+ completion: (void (^)(BOOL finished))completion
+{
+ // UIPageViewController is ridiculous. Making it jump to a specific page
is tricky - it
+ // will not then swipe back or forward correctly. This method fixes that.
Use it rather
+ // than calling UIPageViewController's "setViewControllers" method
directly.
+ // Based on: http://stackoverflow.com/a/18602186
+
+ __weak ReferencesVC *weakSelf = self;
+ [self.pageController setViewControllers: viewControllers
+ direction: direction
+ animated: animated
+ completion: ^(BOOL finished) {
+ if (!weakSelf.pageController) return;
+ dispatch_async(dispatch_get_main_queue(),
^{
+ [weakSelf.pageController
setViewControllers: viewControllers
+
direction: direction
+
animated: NO
+
completion: ^(BOOL done){
+
[weakSelf refViewDidAppear:weakSelf.topPageControl.currentPage];
+ }];
+ });
+ }];
+}
+
+- (void)pageViewController: (UIPageViewController *)pageViewController
+ didFinishAnimating: (BOOL)finished
+ previousViewControllers: (NSArray *)previousViewControllers
+ transitionCompleted: (BOOL)completed
+{
+ // UIPageViewController was swiped.
+ // Update the UIPageControl dots to reflect the UIPageViewController
selection.
+ ReferenceVC *currentView = [pageViewController.viewControllers
objectAtIndex:0];
+ self.topPageControl.currentPage = currentView.index;
+
+ [self refViewDidAppear:self.topPageControl.currentPage];
+}
+
+- (ReferenceVC *)viewControllerAtIndex:(NSInteger)index
+{
+ if (index < 0) return nil;
+ if (index >= self.refs.count) return nil;
+
+ ReferenceVC *refVC = [self.storyboard
instantiateViewControllerWithIdentifier:@"ReferenceVC"];
+ refVC.webVC = self.webVC;
+ refVC.index = index;
+ refVC.html = self.refs[index];
+ refVC.linkId = self.linkIds[index];
+ refVC.linkText = self.linkText[index];
+
+ return refVC;
+}
+
+- (UIViewController *)pageViewController: (UIPageViewController
*)pageViewController
+ viewControllerBeforeViewController: (UIViewController *)viewController
+{
+ return [self viewControllerAtIndex:(((ReferenceVC *)viewController).index
- 1)];
+}
+
+- (UIViewController *)pageViewController: (UIPageViewController
*)pageViewController
+ viewControllerAfterViewController: (UIViewController *)viewController
+{
+ return [self viewControllerAtIndex:(((ReferenceVC *)viewController).index
+ 1)];
+}
+
+-(void)topPageControlTapped:(id)sender
+{
+ // UIPageControl was tapped.
+ // Update the UIPageViewController to reflect the UIPageControl selection.
+
+ ReferenceVC *currentView = [self.pageController.viewControllers
objectAtIndex:0];
+ BOOL isTopPageControlAhead = (self.topPageControl.currentPage >
currentView.index);
+
+ id nextVC = isTopPageControlAhead
+ ?
+ [self pageViewController:self.pageController
viewControllerAfterViewController:currentView]
+ :
+ [self pageViewController:self.pageController
viewControllerBeforeViewController:currentView];
+
+ UIPageViewControllerNavigationDirection dir = isTopPageControlAhead
+ ?
+ UIPageViewControllerNavigationDirectionForward
+ :
+ UIPageViewControllerNavigationDirectionReverse;
+
+ if (nextVC) {
+ [self setViewControllers: @[nextVC]
+ direction: dir
+ animated: YES
+ completion: nil];
+ }
+}
+
+-(void)prevButtonTap
+{
+ if (!self.prevButton.enabled) return;
+
+ BOOL isRTL = [WikipediaAppUtils isDeviceLanguageRTL];
+
+ UIPageViewControllerNavigationDirection dir = isRTL
+ ?
+ UIPageViewControllerNavigationDirectionForward
+ :
+ UIPageViewControllerNavigationDirectionReverse;
+
+ [self setViewControllers: @[[self
viewControllerAtIndex:(--self.topPageControl.currentPage)]]
+ direction: dir
+ animated: YES
+ completion: nil];
+}
+
+-(void)nextButtonTap
+{
+ if (!self.nextButton.enabled) return;
+
+ BOOL isRTL = [WikipediaAppUtils isDeviceLanguageRTL];
+
+ UIPageViewControllerNavigationDirection dir = isRTL
+ ?
+ UIPageViewControllerNavigationDirectionReverse
+ :
+ UIPageViewControllerNavigationDirectionForward;
+
+ [self setViewControllers: @[[self
viewControllerAtIndex:(++self.topPageControl.currentPage)]]
+ direction: dir
+ animated: YES
+ completion: nil];
+}
+
+/*
+// Commented out these two methods to hide the built-in UIPageControl.
+// See: http://stackoverflow.com/a/20749979
+- (NSInteger)presentationCountForPageViewController:(UIPageViewController
*)pageViewController {
+ return 5;
+}
+
+- (NSInteger)presentationIndexForPageViewController:(UIPageViewController
*)pageViewController {
+ return 0;
+}
+*/
+
+- (void)didReceiveMemoryWarning
+{
+ [super didReceiveMemoryWarning];
+ // Dispose of any resources that can be recreated.
+}
+
+/*
+#pragma mark - Navigation
+
+// In a storyboard-based application, you will often want to do a little
preparation before navigation
+- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
+{
+ // Get the new view controller using [segue destinationViewController].
+ // Pass the selected object to the new view controller.
+}
+*/
+
+@end
diff --git a/wikipedia/View Controllers/TableOfContents/TOCViewController.m
b/wikipedia/View Controllers/TableOfContents/TOCViewController.m
index 805d9ad..8bcf97b 100644
--- a/wikipedia/View Controllers/TableOfContents/TOCViewController.m
+++ b/wikipedia/View Controllers/TableOfContents/TOCViewController.m
@@ -64,8 +64,6 @@
self.scrollContainer.translatesAutoresizingMaskIntoConstraints = NO;
self.scrollContainer.backgroundColor = [UIColor clearColor];
-
- self.scrollView.scrollsToTop = NO;
// Adjust scrollview content inset when contentSize changes so bottom
entry can be scrolled to top.
[self.scrollView addObserver: self
@@ -76,9 +74,17 @@
[self refreshForCurrentArticle];
}
+- (BOOL)scrollViewShouldScrollToTop:(UIScrollView *)scrollView
+{
+ [self.webVC.webView.scrollView scrollRectToVisible:CGRectMake(0, 0, 1, 1)
animated:YES];
+ return YES;
+}
+
-(void)viewWillDisappear:(BOOL)animated
{
[self.funnel logClose];
+
+ self.webVC.webView.scrollView.scrollsToTop = YES;
[super viewWillDisappear:animated];
}
@@ -87,6 +93,9 @@
{
[super viewDidAppear:animated];
+ self.scrollView.scrollsToTop = YES;
+ self.webVC.webView.scrollView.scrollsToTop = NO;
+
[self.funnel logOpen];
}
diff --git a/wikipedia/View Controllers/WebView/WebViewController.h
b/wikipedia/View Controllers/WebView/WebViewController.h
index b3a9d7a..68ca8d9 100644
--- a/wikipedia/View Controllers/WebView/WebViewController.h
+++ b/wikipedia/View Controllers/WebView/WebViewController.h
@@ -11,6 +11,10 @@
@property (weak, nonatomic) IBOutlet UIWebView *webView;
@property (nonatomic) BOOL bottomMenuHidden;
+@property (nonatomic) BOOL referencesHidden;
+
+-(void)referencesShow;
+-(void)referencesHide;
// Reloads the current article from the core data cache.
// If "invalidateCache" is set to YES the article will be re-downloaded first.
diff --git a/wikipedia/View Controllers/WebView/WebViewController.m
b/wikipedia/View Controllers/WebView/WebViewController.m
index 59bc476..0b02456 100644
--- a/wikipedia/View Controllers/WebView/WebViewController.m
+++ b/wikipedia/View Controllers/WebView/WebViewController.m
@@ -51,6 +51,7 @@
#import "TopMenuContainerView.h"
#import "WikiGlyph_Chars.h"
#import "UINavigationController+TopActionSheet.h"
+#import "ReferencesVC.h"
//#import "UIView+Debugging.h"
@@ -92,8 +93,12 @@
@property (nonatomic) BOOL unsafeToToggleTOC;
@property (weak, nonatomic) BottomMenuViewController *bottomMenuViewController;
+@property (weak, nonatomic) ReferencesVC *referencesVC;
+@property (weak, nonatomic) IBOutlet UIView *referencesContainerView;
@property (strong, nonatomic) NSLayoutConstraint
*bottomBarViewBottomConstraint;
+@property (strong, nonatomic) IBOutlet NSLayoutConstraint
*referencesContainerViewBottomConstraint;
+@property (strong, nonatomic) IBOutlet NSLayoutConstraint
*referencesContainerViewHeightConstraint;
@property (copy) NSString *jumpToFragment;
@@ -235,7 +240,8 @@
-
+//self.referencesContainerView.layer.borderWidth = 10;
+//self.referencesContainerView.layer.borderColor = [UIColor redColor].CGColor;
}
@@ -313,6 +319,7 @@
[super viewWillAppear:animated];
self.bottomMenuHidden = ROOT.topMenuHidden;
+ self.referencesHidden = YES;
ROOT.topMenuViewController.navBarMode = NAVBAR_MODE_DEFAULT;
[ROOT.topMenuViewController updateTOCButtonVisibility];
@@ -451,6 +458,9 @@
[self.view setNeedsUpdateConstraints];
self.webView.transform = CGAffineTransformIdentity;
+
+ self.referencesContainerView.transform =
CGAffineTransformIdentity;
+
self.bottomBarView.transform =
CGAffineTransformIdentity;
self.webViewRightConstraint.constant = 0;
@@ -501,8 +511,10 @@
animations: ^{
self.bottomMenuHidden = YES;
+ self.referencesHidden = YES;
[self.view setNeedsUpdateConstraints];
self.webView.transform = xf;
+ self.referencesContainerView.transform = xf;
self.bottomBarView.transform = xf;
self.webViewRightConstraint.constant = [self
tocGetWidthForWebViewScale:webViewScale];
[self.view layoutIfNeeded];
@@ -608,7 +620,9 @@
if (!currentArticleTitle || (currentArticleTitle.length == 0)) return;
if (recognizer.state == UIGestureRecognizerStateEnded){
- [self tocShow];
+ if (self.referencesHidden) {
+ [self tocShow];
+ }
}
}
@@ -809,6 +823,8 @@
[weakSelf tocHide];
return;
}
+
+ if(!weakSelf.referencesHidden) [weakSelf referencesHide];
// @todo merge this link title extraction into MWSite
if ([href hasPrefix:@"/wiki/"]) {
@@ -896,10 +912,21 @@
// nonAnchorTouchEndedWithoutDragging is used so TOC may be hidden if
user tapped, but did *not* drag.
// Used because UIWebView is difficult to attach one-finger touch
events to.
[weakSelf tocHide];
+
+ [weakSelf referencesHide];
}];
[self.bridge addListener:@"referenceClicked" withBlock:^(NSString
*messageType, NSDictionary *payload) {
- NSLog(@"referenceClicked: %@", payload);
+
+ if([weakSelf tocDrawerIsOpen]){
+ [weakSelf tocHide];
+ return;
+ }
+
+ //NSLog(@"referenceClicked: %@", payload);
+ weakSelf.referencesVC.payload = payload;
+ [weakSelf referencesShow];
+
}];
self.unsafeToScroll = NO;
@@ -1089,6 +1116,8 @@
if (fabsf(distanceScrolled) < minPixelsScrolled) return;
[ROOT animateTopAndBottomMenuHidden:((distanceScrolled > 0) ? NO :
YES)];
+
+ [self referencesHide];
}
}
@@ -1106,6 +1135,8 @@
- (BOOL)scrollViewShouldScrollToTop:(UIScrollView *)scrollView
{
+ [self referencesHide];
+
// Called when the title bar is tapped.
[self animateTopAndBottomMenuReveal];
return YES;
@@ -1136,6 +1167,9 @@
//[[SessionSingleton sharedInstance].zeroConfigState toggleFakeZeroOn];
//[self toggleImageSheet];
+
+ //ReferencesVC *referencesVC = [self.navigationController.storyboard
instantiateViewControllerWithIdentifier:@"ReferencesVC"];
+ //[self presentViewController:referencesVC animated:YES completion:^{}];
}
-(void)toggleImageSheet
@@ -1927,6 +1961,11 @@
if ([segue.identifier isEqualToString:
@"BottomMenuViewController_embed2"]) {
self.bottomMenuViewController = (BottomMenuViewController *)
[segue destinationViewController];
}
+
+ if ([segue.identifier isEqualToString: @"ReferencesVC_embed"]) {
+ self.referencesVC = (ReferencesVC *) [segue destinationViewController];
+ self.referencesVC.webVC = self;
+ }
}
-(void)setBottomMenuHidden:(BOOL)bottomMenuHidden
@@ -2030,4 +2069,64 @@
[alert show];
}
+#pragma mark Refs
+
+-(void)setReferencesHidden:(BOOL)referencesHidden
+{
+ if (self.referencesHidden == referencesHidden) return;
+
+ _referencesHidden = referencesHidden;
+
+ [self updateReferencesHeightAndBottomConstraints];
+
+ if (referencesHidden) {
+ // Cause the highlighted ref link in the webView to no longer be
highlighted.
+ [self.referencesVC reset];
+ }
+
+ // Fade out refs when hidden.
+ CGFloat alpha = referencesHidden ? 0.0 : 1.0;
+
+ self.referencesContainerView.alpha = alpha;
+}
+
+-(void)updateReferencesHeightAndBottomConstraints
+{
+ CGFloat percentOfHeight =
UIInterfaceOrientationIsPortrait(self.interfaceOrientation) ? 0.4 : 0.6;
+ if(UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) percentOfHeight
*= 0.5;
+ NSNumber *refsHeight = @(self.view.frame.size.height * percentOfHeight);
+ CGFloat f = self.referencesHidden ? refsHeight.integerValue : 0;
+ self.referencesContainerViewBottomConstraint.constant = f;
+ self.referencesContainerViewHeightConstraint.constant =
refsHeight.integerValue;
+}
+
+-(void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
duration:(NSTimeInterval)duration
+{
+ [self updateReferencesHeightAndBottomConstraints];
+}
+
+-(void)referencesShow
+{
+ if (!self.referencesHidden) return;
+ [UIView animateWithDuration: 0.16
+ delay: 0.0f
+ options: UIViewAnimationOptionBeginFromCurrentState
+ animations: ^{
+ self.referencesHidden = NO;
+ [self.view layoutIfNeeded];
+ }completion:nil];
+}
+
+-(void)referencesHide
+{
+ if (self.referencesHidden) return;
+ [UIView animateWithDuration: 0.16
+ delay: 0.0f
+ options: UIViewAnimationOptionBeginFromCurrentState
+ animations: ^{
+ self.referencesHidden = YES;
+ [self.view layoutIfNeeded];
+ }completion:nil];
+}
+
@end
diff --git a/wikipedia/assets/index.html b/wikipedia/assets/index.html
index a207b8b..4105d36 100644
--- a/wikipedia/assets/index.html
+++ b/wikipedia/assets/index.html
@@ -8,6 +8,13 @@
<base href="https://wikipedia.org">
+ <style type="text/css">
+ /* Note: this was added so ref link taps don't show underline. Move
upstream later if possible. */
+
+ a:hover {text-decoration: none;}
+
+ </style>
+
</head>
<body>
<div class="content" id="content">
diff --git a/www/index.html b/www/index.html
index a207b8b..4105d36 100644
--- a/www/index.html
+++ b/www/index.html
@@ -8,6 +8,13 @@
<base href="https://wikipedia.org">
+ <style type="text/css">
+ /* Note: this was added so ref link taps don't show underline. Move
upstream later if possible. */
+
+ a:hover {text-decoration: none;}
+
+ </style>
+
</head>
<body>
<div class="content" id="content">
--
To view, visit https://gerrit.wikimedia.org/r/150964
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: Ie3ad35d6065c874eca0d7289cf190bc3e2bc8156
Gerrit-PatchSet: 1
Gerrit-Project: apps/ios/wikipedia
Gerrit-Branch: master
Gerrit-Owner: Mhurd <[email protected]>
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits