diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..063b0e4 --- /dev/null +++ b/.gitignore @@ -0,0 +1,7 @@ +.DS_Store +Thumbs.db +db.json +*.log +node_modules/ +public/ +.deploy*/ \ No newline at end of file diff --git a/2013/05/12/2013-05-12-first-blog/index.html b/2013/05/12/2013-05-12-first-blog/index.html deleted file mode 100644 index 8533a52..0000000 --- a/2013/05/12/2013-05-12-first-blog/index.html +++ /dev/null @@ -1,256 +0,0 @@ - - - - - - Octopress 第一篇博客 | Wang Rui's Blog - - - - - - - - - - - - - - - - - - - - - - - -
-
- -
-
- -
- - -
- - -

- Octopress 第一篇博客 -

- - -
- -
- -

这是搭建好Octopress写的第一篇博客,搭建过程中遇到了不少麻烦,但最后还是成功搭建出来了,感觉还不错。 还有很多东
西需要琢磨,比如主题、markdown语法、博客写作….总之,需要花时间折腾一下才行。

- - -
- -
- - - - - -
- - -
- -
- - - - -
-
- - - -
-
- -
- -
-
- - -
- - - - - - - - - - - - - - -
- - \ No newline at end of file diff --git a/2013/05/14/2013-05-14-octopress-pei-zhi/index.html b/2013/05/14/2013-05-14-octopress-pei-zhi/index.html deleted file mode 100644 index 7e8ac1e..0000000 --- a/2013/05/14/2013-05-14-octopress-pei-zhi/index.html +++ /dev/null @@ -1,273 +0,0 @@ - - - - - - Octopress 配置 | Wang Rui's Blog - - - - - - - - - - - - - - - - - - - - - - - -
-
- -
-
- -
- - -
- - -

- Octopress 配置 -

- - -
- -
- -

在我的配置过程中出现很多问题,比如说tag-cloud不能显示,中文不能支持,还有添加评论、日历的插件没有搞上去。这个真的太考验动手能力了……..
说实话,我更喜欢博客园写博客。 以后慢慢的熟练吧! 下面转载几篇比较好的配置教程:

- - - -
- -
- - - - - -
- - -
- -
- - - - -
-
- - - -
-
- -
- -
-
- - -
- - - - - - - - - - - - - - -
- - \ No newline at end of file diff --git a/2014/01/13/2014-01-13-id-vs-instance/index.html b/2014/01/13/2014-01-13-id-vs-instance/index.html deleted file mode 100644 index 8fbe12b..0000000 --- a/2014/01/13/2014-01-13-id-vs-instance/index.html +++ /dev/null @@ -1,279 +0,0 @@ - - - - - - id vs instancetype | Wang Rui's Blog - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- -
-
- -
- - -
- - -

- id vs instancetype -

- - -
- -
- -

不知道从什么时候开始IOS的SDK里多了一个叫instancetype的东西,顾名思义返回的就是一个实例对象,所以也没有深究。 但是这玩意和以前的id有什么区别呢,突然比较好奇。 上网查看了下相关的资料,自己也做了下测试,在这里记录一下。

-
    -
  • 首先一个很重要的区别,id可以作为函数的参数和返回值,而instancetyp则只能作为返回值;

    -
  • -
  • 其他区别,我用简单的话来概括就是:

    -

    如果返回的是instancetype,那么编译器是知道你返回的具体对象是什么类型,当你向这个实例发送不属于这个类的消息时,编译器则会报错。

    - -

    而id则是向它可以发送任何消息的,所以编译器不会报错,编译能通过

    - -

    但是有一种特殊情况: 我们知道- (id)init 这个方法返回的是id,但是当你用这个方法生成的实例,向其发送不属于这个类的消息时,编译器也会报错。

    - -

    这是为什么呢,不是可以向id发送任意消息吗? 原来这是因为编译器默认的初始化方法返回的是instancetype,你看着是id,但编译器实现时就是给你返回的是instancetype! 当我们用类方法返回的id,编译器才会真正的当成id处理。

    -
  • -
-

###总结
instancetype的出现,可以避免程序在运行时向某个对象发送不是它的消息引起崩溃,因为编译的时候就不让你通过。所以当你返回的对象确定为这个类的实例时,尽量使用instancetpye吧。 比如经常使用的单例模式,则可声明返回的为instancetype。
仅仅是自己的理解,如有不对之处,请大家指正!

-

###参考文章
instancetype

- - -
- -
- - - - - -
- - -
- -
- - - - -
-
- - - -
-
- -
- -
-
- - -
- - - - - - - - - - - - - - -
- - \ No newline at end of file diff --git a/2014/01/22/2014-01-22-mantle-use/index.html b/2014/01/22/2014-01-22-mantle-use/index.html deleted file mode 100644 index d2017f9..0000000 --- a/2014/01/22/2014-01-22-mantle-use/index.html +++ /dev/null @@ -1,301 +0,0 @@ - - - - - - Mantle 初步使用 | Wang Rui's Blog - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- -
-
- -
- - -
- - -

- Mantle 初步使用 -

- - -
- -
- -

最近接触到了Mantle这个东西,感觉很不错,在此与各位分享一下。

-

###前言
在开发的过程中,我们常常会从网络获取数据,而数据通常又为JSON格式。 这时比较常见的做法是把JSON数据转为Model对象,这样我们可以从Model对象的属性读取数据。 但是常常会面临如下一些问题:

-
    -
  • 每次都要用 -initWithDictionarty:(NSDictionary *)dict 等类似的方法初始化,把JSON数据里的值一个一个的赋值给Modeld对象的属性,深深的感觉到自己在做重复的工作,有木有!

    -
  • -
  • 当你需要的某个数据在JSON字典数据里层次很深时,需要不断的使用 [[obj objectForKey:@"key"] objectAtIndex:index] objectForKey:@""]... 这样很长的代码,是不是感觉很不爽!

    -
  • -
  • 服务器给你返回的数据不是你期望的,例如:有些时候你需要的是一个NSString类型,但给你的是一个NSNumber。 有时你需要的是一个NSDate类型,但给你的是一个NSString类型,你还不得不去做一些判断,写一些转换的代码。 还有一种严重的情况,由于服务器故障,给你返回了一个NSNull,如果你没有做一些判断处理,那么这时你的程序崩溃的几率很大!

    -
  • -
  • 如何从这个Model对象,再还原成之前的JSON字典数据? 其次,你想把这个Model对象存储下来的话,那么你不得不自己去处理NSCoding协议等一些烦人的问题,又是一些重复工作!

    -
  • -
-

有没有办法可以很优雅的解决这些问题呢,这就是今天要说的Mantle框架。

-

###什么是Mantle?
Mantle是github的工程师们弄出来的东西,github主页在此,
引用如下:

Mantle makes it easy to write a simple model layer for your Cocoa or Cocoa Touch application.

-

-

###使用
下面就来说一下怎么使用,首先新建一个空的工程,把Mantle的代码下载下来,拖入你的工程。 我建议使用CocoaPods来管理第三方库,反正我就是这样干的,非常简单方便。 浏览一下框架的目录,大概如下图所示:

- -

居然这么多文件! 不要害怕,我们常用到的就是MTLJSONAdapterMTLModle而已。 MTLModel是一个抽象类,它帮我们做了很多工作,比如解决前言里提出的一些问题。 我们要建的Model类应该继承于它,此外你的继承类一定还要实现MTLJSONSerializing协议。 MTLJSONAdapter则是帮我们把JSON数据绑定到Model的属性里,当然,你不用担心会出现NSNull的情况,因为转换后它会自动设置成nil;

-

我们新建一个继承 MTLModel 的类,叫做 TestDataModel。 我们将从这个地址获取测试数据。 现在把想要的数据声明到头文件里

-
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

//TestDataModel.h
#import <Mantle/Mantle.h>

@interface TestDataModel : MTLModel<MTLJSONSerializing>

@property (nonatomic, strong) NSDate *date;
@property (nonatomic, strong) NSNumber *humidity;
@property (nonatomic, strong) NSNumber *temperature;
@property (nonatomic, strong) NSNumber *tempHigh;
@property (nonatomic, strong) NSNumber *tempLow;
@property (nonatomic, strong) NSString *locationName;
@property (nonatomic, strong) NSDate *sunrise;
@property (nonatomic, strong) NSDate *sunset;
@property (nonatomic, strong) NSString *conditionDescription;
@property (nonatomic, strong) NSString *condition;
@property (nonatomic, strong) NSNumber *windBearing;
@property (nonatomic, strong) NSNumber *windSpeed;

@end
-

TestDataModel.m文件里,实现MTLJSONSerializing协议里的+ (NSDictionary *)JSONKeyPathsByPropertyKey 方法。

-
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

//TestDataModel.m
#import "TestDataModel.h"

@implementation TestDataModel

+ (NSDictionary *)JSONKeyPathsByPropertyKey {
return @{
@"date": @"dt", //将JSON字典里dt键对应的值,赋值给date属性
@"locationName": @"name",
@"humidity": @"main.humidity",
@"temperature": @"main.temp",//这个点是什么意思呢,表示将main键对应的子字典里,
//temp键对应的值赋给temperature属性。
//我们不用再写 objectForKey]objectForKey]..这种代码了。
//注意了:当main键对应的是数组时,main.temp返回的
//为所有temp键对应值的数组合集

@"tempHigh": @"main.temp_max",
@"tempLow": @"main.temp_min",
@"sunrise": @"sys.sunrise",
@"sunset": @"sys.sunset",
@"conditionDescription": @"weather.description",
@"condition": @"weather.main",
@"icon": @"weather.icon",
@"windBearing": @"wind.deg",
@"windSpeed": @"wind.speed",
};
}
-

解释都在注释里。 Model类到此可以用了。 现在我们在AppDelegate.m里,编写相关的测试代码

-
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
NSURL *url = [NSURL URLWithString:@"http://api.openweathermap.org/data/2.5/weather?lat=37.785834&lon=-122.406417&units=imperial"];
[NSURLConnection sendAsynchronousRequest:[NSURLRequest requestWithURL:url]
queue:[NSOperationQueue mainQueue]
completionHandler:^(NSURLResponse* response, NSData* data, NSError* connectionError){
if (!connectionError) {
NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:data
options:NSJSONReadingMutableContainers
error:nil];
//将JSON数据和Model的属性进行绑定
TestDataModel *model = [MTLJSONAdapter modelOfClass:[TestDataModel class]
fromJSONDictionary:dict
error:nil];
NSLog(@"%@",model);
}
}];

}
-

设置断点到15行,控制台显示如下图:

- -

可以看到所有属性值均已设置好了。 强大吧! 等等…这好像和我们期望的类型不太一样,我们声明的date是一个NSDate型,但这里却是NSNumber。JSON数据里解析出来的就是NSNumber,那要怎么转化为我们期望的NSDate呢? Mantle为我们提供了强大的转换机制。 继续回到TestDataModel.m文件里。添加如下代码:

-
1
2
3
4
5
6
7
8
9
//TestDataModel.m

+ (NSValueTransformer *)dateJSONTransformer {
return [MTLValueTransformer reversibleTransformerWithForwardBlock:^(NSNumber *dateNum) {
return [NSDate dateWithTimeIntervalSince1970:dateNum.floatValue];
} reverseBlock:^(NSDate *date) {
return [NSString stringWithFormat:@"%f",[date timeIntervalSince1970]];
}];
}
-

再次运行,控制台结果如下图:

- -

看见了吗,date已经成功转换为NSDate了! 原来,上面的代码是要告知Mantle,赋值时要先进行转换,原始JSON里是一个NSNumber,现在转换为一个NSDate并返回。 其他属性需要转换的都可以这样做,方法命名规则是 属性JSONTransformer,那么在对这个属性进行赋值时就会调用这个方法先进行转换。当JSON数据里有NSNull的类型时,我们不用做任何处理,会自动将该属性置为nil;

-

那reverseBlock是干什么的呢? 当要把Model转换回JSON数据时,如果设置了返回值,那么会将NSDate转回NSNumber返回JSON数据。 我们可以调用 MTLJSONAdapter

-
1
2
3
4
5
6
7
8
9
10
11
+ (NSDictionary *)JSONDictionaryFromModel:(MTLModel<MTLJSONSerializing> *)model;
```

方法将一个Model实例转回JSON数据。


####Model对象的存储:
由于MTLModel已经帮我们实现了NSCoding协议, 要把一个Model对象存储到本地就相当简单了,只需一行代码:

``` objc
[NSKeyedArchiver archiveRootObject:model toFile:path];
-

解档时同样简单:

-
1
TestDataModel *unachiveModel = [NSKeyedUnarchiver unarchiveObjectWithFile:path];
-

Mantle还可以结合CoreData使用,这里不说了。 至此,Mantle的简单使用就介绍完了! 如有什么不对之处,请各位谅解和指正!

-

###原理

-

没有深入研究源码,准备抽时间仔细研究一把。 大致看了下,Mantle主要使用了一些Runtime的东西,获取到所有propertiy属性进行绑定。 代码看起来有种不明觉厉的感觉,不得不感叹github上的牛人真多! 想深入研究的同学可以多看下源码!

-

###参考文章

-

https://github.com/MantleFramework/Mantle

- - -
- -
- - - - - -
- - -
- -
- - - - -
-
- - - -
-
- -
- -
-
- - -
- - - - - - - - - - - - - - -
- - \ No newline at end of file diff --git a/2014/09/11/2014-09-11-nsinputstream-and-nsoutputstream/index.html b/2014/09/11/2014-09-11-nsinputstream-and-nsoutputstream/index.html deleted file mode 100644 index 80ac546..0000000 --- a/2014/09/11/2014-09-11-nsinputstream-and-nsoutputstream/index.html +++ /dev/null @@ -1,277 +0,0 @@ - - - - - - NSInputStream 和 NSOutputStream | Wang Rui's Blog - - - - - - - - - - - - - - - - - - - - - - - -
-
- -
-
- -
- - -
- - -

- NSInputStream 和 NSOutputStream -

- - -
- -
- -

对于 NSInputStream 和 NSOutputStream 一直没怎么搞清楚,今天抽一些时间在此记录一下!

-

NSInputStream 与 NSOutputStream 都继承于 NSStream, NSStream 是一个抽象的基类, 规定了Stream共有的一些行为…

- -

###什么是Stream

-

Stream翻译成为流,它是对我们读写文件的一个抽象。 你可以这样想象,当你读文件和写文件的时候,文件的内容就像水流一样哗哗的
像你流过来或者流给别人,这样岂不是很爽。 而Stream就帮我们做了这样的事情, 实际上,它是把文件的内容,一小段一小段的读出或
写入,来到达这样的效果

-

###NSStream

-

NSStream 是Cocoa平台下对流这个概念的实现类, NSInputStream 和 NSOutputStream 则是它的两个子类,分别对应了读文件和
写文件。

-

###NSInputStream

-

NSInputStream 对应的是读文件,所以要记住它是要将文件的内容读到内存(你声明的一段buffer)里, 下面一段是测试代码

-
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
36
37
38
39
40
41
42
43
44
45
46
47

- (void)doTestInputStream {
NSString *path = @"/Users/usr/Desktop/stream.txt";

NSInputStream *readStream = [[NSInputStream alloc]initWithFileAtPath:path];
[readStream setDelegate:self];

[readStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes];
[readStream open]; //调用open开始读文件
}

- (void)stream:(NSStream *)aStream handleEvent:(NSStreamEvent)eventCode {
switch (eventCode) {
case NSStreamEventHasBytesAvailable:{

uint8_t buf[1024];

NSInputStream *reads = (NSInputStream *)aStream;
NSInteger blength = [reads read:buf maxLength:sizeof(buf)]; //把流的数据放入buffer
NSData *data = [NSData dataWithBytes:(void *)buf length:blength];

NSString *string = [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding];
NSLog(@"%@",string);
}
break;


//错误和无事件处理
case NSStreamEventErrorOccurred:{

}
break;
case NSStreamEventNone:
break;

//打开完成
case NSStreamEventOpenCompleted: {
NSLog(@"NSStreamEventOpenCompleted");
}
break;

default:
break;
}
}

@end
-

###NSOutputStream

-

NSOutputStream 对应的是写文件,它是要将已存在的内存(buffer)里的数据写入文件, 下面同样一段是测试代码

-
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
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72

- (NSData *)dataWillWrite {
static NSData *data = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
data = [NSData dataWithContentsOfFile:@"/Users/usr/Desktop/stream.txt"];
});

return data;
}

- (void)doTestOutputStream {
NSString *path = @"/Users/usr/Desktop/stream-write.txt";

NSOutputStream *writeStream = [[NSOutputStream alloc] initToFileAtPath:path append:YES];
[writeStream setDelegate:self];

[writeStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes];
[writeStream open];
}

- (void)stream:(NSStream *)aStream handleEvent:(NSStreamEvent)eventCode {
switch (eventCode) {
case NSStreamEventHasSpaceAvailable: {

NSInteger bufSize = 5;
uint8_t buf[bufSize];

if (self.location + bufSize > [self dataWillWrite].length) {
[[self dataWillWrite] getBytes:buf
range:NSMakeRange(self.location, self.location + bufSize - [self dataWillWrite].length)];
}
else {
[[self dataWillWrite] getBytes:buf range:NSMakeRange(self.location, bufSize)];
}

NSOutputStream *writeStream = (NSOutputStream *)aStream;
[writeStream write:buf maxLength:sizeof(buf)]; //把buffer里的数据,写入文件

self.location += bufSize;
if (self.location >= [[self dataWillWrite] length] ) { //写完后关闭流
[aStream close];
}

}
break;

case NSStreamEventEndEncountered: {
[aStream close];
}
break;

//错误和无事件处理
case NSStreamEventErrorOccurred:{

}
break;
case NSStreamEventNone:
break;

//打开完成
case NSStreamEventOpenCompleted: {
NSLog(@"NSStreamEventOpenCompleted");


}
break;

default:
break;
}
}
-

用途

NSInputStream 和 NSOutputStream 常用与网络传输中,比如要将一个很大的文件传送给服务器,那么NSInputStream这时候是
很好的选择, 我们可以查看到 NSURLRequest 有一个属性叫HTTPBodyStream, 这时只要设置好一个NSInputStream的实例就可以
了,最大的好处就是可以节省我们很多的内存。

-

另外要说明的是,NSInputStream 和 NSOutputStream其实是对 CoreFoundation 层对应的CFReadStreamRef 和 CFWriteStreamRef
的高层抽象。在使用CFNetwork时,常常会使用到CFReadStreamRef 与 CFWriteStreamRef。 下面是一段相关代码

-
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
36
37
38
39
40
41
42
43
44

// Keep a reference to self to use for controller callbacks
//
CFStreamClientContext ctx = {0, (__bridge void *)(self), NULL, NULL, NULL};

// Get callbacks for stream data, stream end, and any errors
//
CFOptionFlags registeredEvents = (kCFStreamEventHasBytesAvailable | kCFStreamEventEndEncountered | kCFStreamEventErrorOccurred);

// Create a read-only socket
//
CFReadStreamRef readStream;
CFStreamCreatePairWithSocketToHost(kCFAllocatorDefault, (__bridge CFStringRef)host, (UInt32)port, &readStream, NULL);

// Schedule the stream on the run loop to enable callbacks
//
if (CFReadStreamSetClient(readStream, registeredEvents, socketCallback, &ctx)) {
CFReadStreamScheduleWithRunLoop(readStream, CFRunLoopGetCurrent(), kCFRunLoopCommonModes);

}
else {
[self networkFailedWithErrorMessage:@"Failed to assign callback method"];
return;
}

// Open the stream for reading
//
if (CFReadStreamOpen(readStream) == NO) {
[self networkFailedWithErrorMessage:@"Failed to open read stream"];

return;
}

CFErrorRef error = CFReadStreamCopyError(readStream);
if (error != NULL) {
if (CFErrorGetCode(error) != 0) {
NSString * errorInfo = [NSString stringWithFormat:@"Failed to connect stream; error '%@' (code %ld)", (__bridge NSString*)CFErrorGetDomain(error), CFErrorGetCode(error)];
[self networkFailedWithErrorMessage:errorInfo];
}

CFRelease(error);

return;
}
- - -
- -
- - - - - -
- - -
- -
- - - - -
-
- - - -
-
- -
- -
-
- - -
- - - - - - - - - - - - - - -
- - \ No newline at end of file diff --git a/2014/09/12/2014-09-12-clang-compile-arm-file/index.html b/2014/09/12/2014-09-12-clang-compile-arm-file/index.html deleted file mode 100644 index 4bbf788..0000000 --- a/2014/09/12/2014-09-12-clang-compile-arm-file/index.html +++ /dev/null @@ -1,278 +0,0 @@ - - - - - - Mac上用 clang 简单交叉编译arm架构的文件 | Wang Rui's Blog - - - - - - - - - - - - - - - - - - - - - - - -
-
- -
-
- -
- - -
- - -

- Mac上用 clang 简单交叉编译arm架构的文件 -

- - -
- -
- -

在Mac上简单的编译出一个可以在 IOS 上运行的 hello world 程序:

- -
    -
  • 写一个简单的hello world程序,保存到桌面或者其他地方

    -
  • -
  • 终端里cd 到刚才保存的路径

    -
  • -
  • 运行命令:

    -
  • -
-
1
2
3
4
5
6
7

// -arch 表示要编译的架构 这里为armv7.
// -isysroot 指定头文件的根路径
$ clang -arch armv7 -o hello hello.c -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS7.1.sdk

//也可以使用xcrun
$ xcrun -sdk iphoneos clang -arch armv7 -o hello hello.c //xcrun -sdk 会使用最新的sdk去编译
-
    -
  • 使用file命令查看编译出来的文件是什么架构
  • -
-
1
2

$ file hello //output: 'hello: Mach-O executable arm'
-
    -
  • scp 到越狱ios设备运行
  • -
-
1
2

$ ./hello
-

成功输出 hello world

- - -
- -
- - - - - -
- - -
- -
- - - - -
-
- - - -
-
- -
- -
-
- - -
- - - - - - - - - - - - - - -
- - \ No newline at end of file diff --git a/2015/03/08/2015-03-08-toll-free-bridging/index.html b/2015/03/08/2015-03-08-toll-free-bridging/index.html deleted file mode 100644 index bba3ee4..0000000 --- a/2015/03/08/2015-03-08-toll-free-bridging/index.html +++ /dev/null @@ -1,262 +0,0 @@ - - - - - - Toll Free Bridging 的秘密 | Wang Rui's Blog - - - - - - - - - - - - - - - - - - - - - - - -
-
- -
-
- -
- - -
- - -

- Toll Free Bridging 的秘密 -

- - -
- -
- -

Toll free briding 是用于 Foundation对象和Core Foundation对象间无缝转换的一种方法。首先,我们来看看下面代码:

1
2
3
4
5
6

CFStringRef cfStr = SomeFunctionThatReturnsCFString();
NSUInteger length = [(NSString *)cfStr length];

NSString *nsStr = [self someString];
CFIndex length = CFStringGetLength((CFStringRef)nsStr);

-

我们可以将一个 CFStringRef 类型的变量通过指针转换为 NSString * 类型, 然后直接当作NSString 使用, 向其发送消息。
同时,我们也可以将 NSString *通过指针转换为 CFStringRef, 即可当作CFStringRef,对于 CFStringRef 申明的C层级的
API 均能使用。这便是官方所说得 Toll free briding。

-

那么这一切是如何做到的,内部发生了什么?

-

###CF 转为 OBJC
首先,我们来看看CF对象是怎样转为OBJC对象的。 这个方向的转换比较简单。 在OBJC的类里,绝大多数能进行bridging的类都是一层抽象封装,叫做类族。如NSString, 我们在得到真正的实例时是它的一个私有子类NSCFString。 而CFStringRefNSCFString 对象具有相同的内存布局, CFStringRef 的前4个字节也是一个 isa 指针
,指向 NSCFString 类。 由OBJC的消息发送机制我们可以知道,这时候,对其发送OBJC的消息,和对OBJC的对应对象发送消息是一模一样的!

-

###OBJC 转为 CF
还以NSString为列。上面我们说了:CFStringRefNSCFString 对象具有相同的内存布局。 这时候,你可能要说了,既然是
相同的内存布局,直接作指针转换就好了! OBJC对象即可当作CF对象! 可是,有一些情况比较例外。如果我们写了一个类,继承于
NSString, 重写了 length 方法。 那么这时候,这个对象则和 CFStringRef 不再具有相同的内存布局,它们的isa指针指向不同的
类了。 但是这种情况我们任然是可以作bridging的。这又是怎么办到的?

-

CF在他的API里,都做了一个OBJC方法名的映射,如 CFStringGetLength:

-
1
2
3
4
5
6
7
8

CFIndex CFStringGetLength(CFStringRef str) {

CF_OBJC_FUNCDISPATCH0(__kCFStringTypeID, CFIndex, str, "length");

__CFAssertIsString(str);
return __CFStrLength(str);
}
-

CFStringGetLength 映射了 NSStringlength方法!

-

CF_OBJC_FUNCDISPATCH0 就是要去判断传进来的str究竟是不是NSCFString,如果是则调用 __CFStrLength 函数返回。
如果不是,则向这个对象发送 length 消息,并返回。 如果我们传入的是自己继承NSString的对象,
那么这时候则会向这个对象发送length消息,重写的方法就得到了调用!

-

注:ARC下的bridging,需要用到__bridge, __bridge_retained, __bridge_transfer修饰符,本文不作讨论。

-

###参考
Friday Q&A 2010-01-22: Toll Free Bridging Internals

- - -
- -
- - - - - -
- - -
- -
- - - - -
-
- - - -
-
- -
- -
-
- - -
- - - - - - - - - - - - - - -
- - \ No newline at end of file diff --git a/_config.yml b/_config.yml new file mode 100644 index 0000000..0d9c789 --- /dev/null +++ b/_config.yml @@ -0,0 +1,73 @@ +# Hexo Configuration +## Docs: http://hexo.io/docs/configuration.html +## Source: https://github.com/hexojs/hexo/ + +# Site +title: Wang Rui's Blog +subtitle: A great ship asks deep water. +description: +author: Wang Rui +language: +timezone: + +# URL +## If your site is put in a subdirectory, set url as 'http://yoursite.com/child' and root as '/child/' +url: http://yoursite.com +root: / +permalink: :year/:month/:day/:title/ +permalink_defaults: + +# Directory +source_dir: source +public_dir: public +tag_dir: tags +archive_dir: archives +category_dir: categories +code_dir: downloads/code +i18n_dir: :lang +skip_render: + +# Writing +new_post_name: :title.md # File name of new posts +default_layout: post +titlecase: false # Transform title into titlecase +external_link: true # Open external links in new tab +filename_case: 0 +render_drafts: false +post_asset_folder: false +relative_link: false +future: true +highlight: + enable: true + line_number: true + auto_detect: true + tab_replace: + +# Category & Tag +default_category: uncategorized +category_map: +tag_map: + +# Date / Time format +## Hexo uses Moment.js to parse and display date +## You can customize the date format as defined in +## http://momentjs.com/docs/#/displaying/format/ +date_format: YYYY-MM-DD +time_format: HH:mm:ss + +# Pagination +## Set per_page to 0 to disable pagination +per_page: 10 +pagination_dir: page + +duoshuo_shortname: wangrui + +# Extensions +## Plugins: http://hexo.io/plugins/ +## Themes: http://hexo.io/themes/ +theme: landscape + +# Deployment +## Docs: http://hexo.io/docs/deployment.html +deploy: + type: \ No newline at end of file diff --git a/archives/2013/05/index.html b/archives/2013/05/index.html deleted file mode 100644 index 008d61c..0000000 --- a/archives/2013/05/index.html +++ /dev/null @@ -1,231 +0,0 @@ - - - - - - Archives: 2013/5 | Wang Rui's Blog - - - - - - - - - - - - - - - - - - - - - - -
-
- -
-
- - - - - - -
-
- 2013 -
-
- - - - - - - - -
- -
- - - -
-
- -
- -
-
- - -
- - - - - - - - - - - - - - -
- - \ No newline at end of file diff --git a/archives/2013/index.html b/archives/2013/index.html deleted file mode 100644 index 3c31df3..0000000 --- a/archives/2013/index.html +++ /dev/null @@ -1,231 +0,0 @@ - - - - - - Archives: 2013 | Wang Rui's Blog - - - - - - - - - - - - - - - - - - - - - - -
-
- -
-
- - - - - - -
-
- 2013 -
-
- - - - - - - - -
- -
- - - -
-
- -
- -
-
- - -
- - - - - - - - - - - - - - -
- - \ No newline at end of file diff --git a/archives/2014/01/index.html b/archives/2014/01/index.html deleted file mode 100644 index 9cb70c6..0000000 --- a/archives/2014/01/index.html +++ /dev/null @@ -1,231 +0,0 @@ - - - - - - Archives: 2014/1 | Wang Rui's Blog - - - - - - - - - - - - - - - - - - - - - - -
-
- -
-
- - - - - - -
-
- 2014 -
-
- - - - - - - - -
- -
- - - -
-
- -
- -
-
- - -
- - - - - - - - - - - - - - -
- - \ No newline at end of file diff --git a/archives/2014/09/index.html b/archives/2014/09/index.html deleted file mode 100644 index 1c4a9df..0000000 --- a/archives/2014/09/index.html +++ /dev/null @@ -1,231 +0,0 @@ - - - - - - Archives: 2014/9 | Wang Rui's Blog - - - - - - - - - - - - - - - - - - - - - - -
-
- -
-
- - - - - - -
-
- 2014 -
-
- - - - - - - - -
- -
- - - -
-
- -
- -
-
- - -
- - - - - - - - - - - - - - -
- - \ No newline at end of file diff --git a/archives/2014/index.html b/archives/2014/index.html deleted file mode 100644 index d09f03e..0000000 --- a/archives/2014/index.html +++ /dev/null @@ -1,269 +0,0 @@ - - - - - - Archives: 2014 | Wang Rui's Blog - - - - - - - - - - - - - - - - - - - - - - -
-
- -
-
- - - - - - -
-
- 2014 -
-
- - - - - - - - - - - - - - - - -
- -
- - - -
-
- -
- -
-
- - -
- - - - - - - - - - - - - - -
- - \ No newline at end of file diff --git a/archives/2015/03/index.html b/archives/2015/03/index.html deleted file mode 100644 index dc77f73..0000000 --- a/archives/2015/03/index.html +++ /dev/null @@ -1,212 +0,0 @@ - - - - - - Archives: 2015/3 | Wang Rui's Blog - - - - - - - - - - - - - - - - - - - - - - -
-
- -
-
- - - - - - -
-
- 2015 -
-
- - - - -
- -
- - - -
-
- -
- -
-
- - -
- - - - - - - - - - - - - - -
- - \ No newline at end of file diff --git a/archives/2015/index.html b/archives/2015/index.html deleted file mode 100644 index abfe2d8..0000000 --- a/archives/2015/index.html +++ /dev/null @@ -1,212 +0,0 @@ - - - - - - Archives: 2015 | Wang Rui's Blog - - - - - - - - - - - - - - - - - - - - - - -
-
- -
-
- - - - - - -
-
- 2015 -
-
- - - - -
- -
- - - -
-
- -
- -
-
- - -
- - - - - - - - - - - - - - -
- - \ No newline at end of file diff --git a/archives/index.html b/archives/index.html deleted file mode 100644 index 0382814..0000000 --- a/archives/index.html +++ /dev/null @@ -1,346 +0,0 @@ - - - - - - Archives | Wang Rui's Blog - - - - - - - - - - - - - - - - - - - - - - -
-
- -
-
- - - - - - -
-
- 2015 -
-
- - - - - - -
- - -
-
- 2014 -
-
- - - - - - - - - - - - - - - - - - -
- - -
-
- 2013 -
-
- - - - - - - - -
- -
- - - -
-
- -
- -
-
- - -
- - - - - - - - - - - - - - -
- - \ No newline at end of file diff --git a/buildBlog.sh b/buildBlog.sh new file mode 100644 index 0000000..40b89ee --- /dev/null +++ b/buildBlog.sh @@ -0,0 +1,33 @@ +#! /bin/zsh + +hexo clean +hexo generate +cd public #到生产的博客的目录 + +git init +git add . +git commit -m "update at `date` " + +git remote add coding git@git.coding.net:ourui/ourui.git >> /dev/null 2>&1 +echo "### Pushing Pages to Coding..." +git push coding master:coding-pages -f + +git remote add origin git@github.com:ourui/ourui.github.com.git >> /dev/null 2>&1 +echo "### Pushing Pages to Github..." +git push origin master:master -f + +echo "### Done" + + +cd .. +echo "### Backup Source to Coding..." +git push coding master:source -f + +echo "### Backup Source to Github..." +git push origin master:source -f + +echo "### Done" + + + + diff --git a/categories/iOS/index.html b/categories/iOS/index.html deleted file mode 100644 index 05242f8..0000000 --- a/categories/iOS/index.html +++ /dev/null @@ -1,298 +0,0 @@ - - - - - - Category: iOS | Wang Rui's Blog - - - - - - - - - - - - - - - - - - - - - - -
-
- -
-
- - - - - - -
-
- 2015 -
-
- - - - - - -
- - -
-
- 2014 -
-
- - - - - - - - - - - - - - - - -
- -
- - - -
-
- -
- -
-
- - -
- - - - - - - - - - - - - - -
- - \ No newline at end of file diff --git a/categories/tools/index.html b/categories/tools/index.html deleted file mode 100644 index 52ae3d5..0000000 --- a/categories/tools/index.html +++ /dev/null @@ -1,231 +0,0 @@ - - - - - - Category: tools | Wang Rui's Blog - - - - - - - - - - - - - - - - - - - - - - -
-
- -
-
- - - - - - -
-
- 2013 -
-
- - - - - - - - -
- -
- - - -
-
- -
- -
-
- - -
- - - - - - - - - - - - - - -
- - \ No newline at end of file diff --git a/css/style.css b/css/style.css deleted file mode 100644 index 6c97ff0..0000000 --- a/css/style.css +++ /dev/null @@ -1,1380 +0,0 @@ -body { - width: 100%; -} -body:before, -body:after { - content: ""; - display: table; -} -body:after { - clear: both; -} -html, -body, -div, -span, -applet, -object, -iframe, -h1, -h2, -h3, -h4, -h5, -h6, -p, -blockquote, -pre, -a, -abbr, -acronym, -address, -big, -cite, -code, -del, -dfn, -em, -img, -ins, -kbd, -q, -s, -samp, -small, -strike, -strong, -sub, -sup, -tt, -var, -dl, -dt, -dd, -ol, -ul, -li, -fieldset, -form, -label, -legend, -table, -caption, -tbody, -tfoot, -thead, -tr, -th, -td { - margin: 0; - padding: 0; - border: 0; - outline: 0; - font-weight: inherit; - font-style: inherit; - font-family: inherit; - font-size: 100%; - vertical-align: baseline; -} -body { - line-height: 1; - color: #000; - background: #fff; -} -ol, -ul { - list-style: none; -} -table { - border-collapse: separate; - border-spacing: 0; - vertical-align: middle; -} -caption, -th, -td { - text-align: left; - font-weight: normal; - vertical-align: middle; -} -a img { - border: none; -} -input, -button { - margin: 0; - padding: 0; -} -input::-moz-focus-inner, -button::-moz-focus-inner { - border: 0; - padding: 0; -} -@font-face { - font-family: FontAwesome; - font-style: normal; - font-weight: normal; - src: url("fonts/fontawesome-webfont.eot?v=#4.0.3"); - src: url("fonts/fontawesome-webfont.eot?#iefix&v=#4.0.3") format("embedded-opentype"), url("fonts/fontawesome-webfont.woff?v=#4.0.3") format("woff"), url("fonts/fontawesome-webfont.ttf?v=#4.0.3") format("truetype"), url("fonts/fontawesome-webfont.svg#fontawesomeregular?v=#4.0.3") format("svg"); -} -html, -body, -#container { - height: 100%; -} -body { - background: #eee; - font: 14px "Helvetica Neue", Helvetica, Arial, sans-serif; - -webkit-text-size-adjust: 100%; -} -.outer { - max-width: 1220px; - margin: 0 auto; - padding: 0 20px; -} -.outer:before, -.outer:after { - content: ""; - display: table; -} -.outer:after { - clear: both; -} -.inner { - display: inline; - float: left; - width: 98.33333333333333%; - margin: 0 0.833333333333333%; -} -.left, -.alignleft { - float: left; -} -.right, -.alignright { - float: right; -} -.clear { - clear: both; -} -#container { - position: relative; -} -.mobile-nav-on { - overflow: hidden; -} -#wrap { - height: 100%; - width: 100%; - position: absolute; - top: 0; - left: 0; - -webkit-transition: 0.2s ease-out; - -moz-transition: 0.2s ease-out; - -ms-transition: 0.2s ease-out; - transition: 0.2s ease-out; - z-index: 1; - background: #eee; -} -.mobile-nav-on #wrap { - left: 280px; -} -@media screen and (min-width: 768px) { - #main { - display: inline; - float: left; - width: 73.33333333333333%; - margin: 0 0.833333333333333%; - } -} -.article-date, -.article-category-link, -.archive-year, -.widget-title { - text-decoration: none; - text-transform: uppercase; - letter-spacing: 2px; - color: #999; - margin-bottom: 1em; - margin-left: 5px; - line-height: 1em; - text-shadow: 0 1px #fff; - font-weight: bold; -} -.article-inner, -.archive-article-inner { - background: #fff; - -webkit-box-shadow: 1px 2px 3px #ddd; - box-shadow: 1px 2px 3px #ddd; - border: 1px solid #ddd; - -webkit-border-radius: 3px; - border-radius: 3px; -} -.article-entry h1, -.widget h1 { - font-size: 2em; -} -.article-entry h2, -.widget h2 { - font-size: 1.5em; -} -.article-entry h3, -.widget h3 { - font-size: 1.3em; -} -.article-entry h4, -.widget h4 { - font-size: 1.2em; -} -.article-entry h5, -.widget h5 { - font-size: 1em; -} -.article-entry h6, -.widget h6 { - font-size: 1em; - color: #999; -} -.article-entry hr, -.widget hr { - border: 1px dashed #ddd; -} -.article-entry strong, -.widget strong { - font-weight: bold; -} -.article-entry em, -.widget em, -.article-entry cite, -.widget cite { - font-style: italic; -} -.article-entry sup, -.widget sup, -.article-entry sub, -.widget sub { - font-size: 0.75em; - line-height: 0; - position: relative; - vertical-align: baseline; -} -.article-entry sup, -.widget sup { - top: -0.5em; -} -.article-entry sub, -.widget sub { - bottom: -0.2em; -} -.article-entry small, -.widget small { - font-size: 0.85em; -} -.article-entry acronym, -.widget acronym, -.article-entry abbr, -.widget abbr { - border-bottom: 1px dotted; -} -.article-entry ul, -.widget ul, -.article-entry ol, -.widget ol, -.article-entry dl, -.widget dl { - margin: 0 20px; - line-height: 1.6em; -} -.article-entry ul ul, -.widget ul ul, -.article-entry ol ul, -.widget ol ul, -.article-entry ul ol, -.widget ul ol, -.article-entry ol ol, -.widget ol ol { - margin-top: 0; - margin-bottom: 0; -} -.article-entry ul, -.widget ul { - list-style: disc; -} -.article-entry ol, -.widget ol { - list-style: decimal; -} -.article-entry dt, -.widget dt { - font-weight: bold; -} -#header { - height: 300px; - position: relative; - border-bottom: 1px solid #ddd; -} -#header:before, -#header:after { - content: ""; - position: absolute; - left: 0; - right: 0; - height: 40px; -} -#header:before { - top: 0; - background: -webkit-linear-gradient(rgba(0,0,0,0.2), transparent); - background: -moz-linear-gradient(rgba(0,0,0,0.2), transparent); - background: -ms-linear-gradient(rgba(0,0,0,0.2), transparent); - background: linear-gradient(rgba(0,0,0,0.2), transparent); -} -#header:after { - bottom: 0; - background: -webkit-linear-gradient(transparent, rgba(0,0,0,0.2)); - background: -moz-linear-gradient(transparent, rgba(0,0,0,0.2)); - background: -ms-linear-gradient(transparent, rgba(0,0,0,0.2)); - background: linear-gradient(transparent, rgba(0,0,0,0.2)); -} -#header-outer { - height: 100%; - position: relative; -} -#header-inner { - position: relative; - overflow: hidden; -} -#banner { - position: absolute; - top: 0; - left: 0; - width: 100%; - height: 100%; - background: url("images/banner.jpg") center #000; - -webkit-background-size: cover; - -moz-background-size: cover; - background-size: cover; - z-index: -1; -} -#header-title { - text-align: center; - height: 40px; - position: absolute; - top: 50%; - left: 0; - margin-top: -20px; -} -#logo, -#subtitle { - text-decoration: none; - color: #fff; - font-weight: 300; - text-shadow: 0 1px 4px rgba(0,0,0,0.3); -} -#logo { - font-size: 40px; - line-height: 40px; - letter-spacing: 2px; -} -#subtitle { - font-size: 16px; - line-height: 16px; - letter-spacing: 1px; -} -#subtitle-wrap { - margin-top: 16px; -} -#main-nav { - float: left; - margin-left: -15px; -} -.nav-icon, -.main-nav-link { - float: left; - color: #fff; - opacity: 0.6; - text-decoration: none; - text-shadow: 0 1px rgba(0,0,0,0.2); - -webkit-transition: opacity 0.2s; - -moz-transition: opacity 0.2s; - -ms-transition: opacity 0.2s; - transition: opacity 0.2s; - display: block; - padding: 20px 15px; -} -.nav-icon:hover, -.main-nav-link:hover { - opacity: 1; -} -.nav-icon { - font-family: FontAwesome; - text-align: center; - font-size: 14px; - width: 14px; - height: 14px; - padding: 20px 15px; - position: relative; - cursor: pointer; -} -.main-nav-link { - font-weight: 300; - letter-spacing: 1px; -} -@media screen and (max-width: 479px) { - .main-nav-link { - display: none; - } -} -#main-nav-toggle { - display: none; -} -#main-nav-toggle:before { - content: "\f0c9"; -} -@media screen and (max-width: 479px) { - #main-nav-toggle { - display: block; - } -} -#sub-nav { - float: right; - margin-right: -15px; -} -#nav-rss-link:before { - content: "\f09e"; -} -#nav-search-btn:before { - content: "\f002"; -} -#search-form-wrap { - position: absolute; - top: 15px; - width: 150px; - height: 30px; - right: -150px; - opacity: 0; - -webkit-transition: 0.2s ease-out; - -moz-transition: 0.2s ease-out; - -ms-transition: 0.2s ease-out; - transition: 0.2s ease-out; -} -#search-form-wrap.on { - opacity: 1; - right: 0; -} -@media screen and (max-width: 479px) { - #search-form-wrap { - width: 100%; - right: -100%; - } -} -.search-form { - position: absolute; - top: 0; - left: 0; - right: 0; - background: #fff; - padding: 5px 15px; - -webkit-border-radius: 15px; - border-radius: 15px; - -webkit-box-shadow: 0 0 10px rgba(0,0,0,0.3); - box-shadow: 0 0 10px rgba(0,0,0,0.3); -} -.search-form-input { - border: none; - background: none; - color: #555; - width: 100%; - font: 13px "Helvetica Neue", Helvetica, Arial, sans-serif; - outline: none; -} -.search-form-input::-webkit-search-results-decoration, -.search-form-input::-webkit-search-cancel-button { - -webkit-appearance: none; -} -.search-form-submit { - position: absolute; - top: 50%; - right: 10px; - margin-top: -7px; - font: 13px FontAwesome; - border: none; - background: none; - color: #bbb; - cursor: pointer; -} -.search-form-submit:hover, -.search-form-submit:focus { - color: #777; -} -.article { - margin: 50px 0; -} -.article-inner { - overflow: hidden; -} -.article-meta:before, -.article-meta:after { - content: ""; - display: table; -} -.article-meta:after { - clear: both; -} -.article-date { - float: left; -} -.article-category { - float: left; - line-height: 1em; - color: #ccc; - text-shadow: 0 1px #fff; - margin-left: 8px; -} -.article-category:before { - content: "\2022"; -} -.article-category-link { - margin: 0 12px 1em; -} -.article-header { - padding: 20px 20px 0; -} -.article-title { - text-decoration: none; - font-size: 2em; - font-weight: bold; - color: #555; - line-height: 1.1em; - -webkit-transition: color 0.2s; - -moz-transition: color 0.2s; - -ms-transition: color 0.2s; - transition: color 0.2s; -} -a.article-title:hover { - color: #258fb8; -} -.article-entry { - color: #555; - padding: 0 20px; -} -.article-entry:before, -.article-entry:after { - content: ""; - display: table; -} -.article-entry:after { - clear: both; -} -.article-entry p, -.article-entry table { - line-height: 1.6em; - margin: 1.6em 0; -} -.article-entry h1, -.article-entry h2, -.article-entry h3, -.article-entry h4, -.article-entry h5, -.article-entry h6 { - font-weight: bold; -} -.article-entry h1, -.article-entry h2, -.article-entry h3, -.article-entry h4, -.article-entry h5, -.article-entry h6 { - line-height: 1.1em; - margin: 1.1em 0; -} -.article-entry a { - color: #258fb8; - text-decoration: none; -} -.article-entry a:hover { - text-decoration: underline; -} -.article-entry ul, -.article-entry ol, -.article-entry dl { - margin-top: 1.6em; - margin-bottom: 1.6em; -} -.article-entry img, -.article-entry video { - max-width: 100%; - height: auto; - display: block; - margin: auto; -} -.article-entry iframe { - border: none; -} -.article-entry table { - width: 100%; - border-collapse: collapse; - border-spacing: 0; -} -.article-entry th { - font-weight: bold; - border-bottom: 3px solid #ddd; - padding-bottom: 0.5em; -} -.article-entry td { - border-bottom: 1px solid #ddd; - padding: 10px 0; -} -.article-entry blockquote { - font-family: Georgia, "Times New Roman", serif; - font-size: 1.4em; - margin: 1.6em 20px; - text-align: center; -} -.article-entry blockquote footer { - font-size: 14px; - margin: 1.6em 0; - font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; -} -.article-entry blockquote footer cite:before { - content: "—"; - padding: 0 0.5em; -} -.article-entry .pullquote { - text-align: left; - width: 45%; - margin: 0; -} -.article-entry .pullquote.left { - margin-left: 0.5em; - margin-right: 1em; -} -.article-entry .pullquote.right { - margin-right: 0.5em; - margin-left: 1em; -} -.article-entry .caption { - color: #999; - display: block; - font-size: 0.9em; - margin-top: 0.5em; - position: relative; - text-align: center; -} -.article-entry .video-container { - position: relative; - padding-top: 56.25%; - height: 0; - overflow: hidden; -} -.article-entry .video-container iframe, -.article-entry .video-container object, -.article-entry .video-container embed { - position: absolute; - top: 0; - left: 0; - width: 100%; - height: 100%; - margin-top: 0; -} -.article-more-link a { - display: inline-block; - line-height: 1em; - padding: 6px 15px; - -webkit-border-radius: 15px; - border-radius: 15px; - background: #eee; - color: #999; - text-shadow: 0 1px #fff; - text-decoration: none; -} -.article-more-link a:hover { - background: #258fb8; - color: #fff; - text-decoration: none; - text-shadow: 0 1px #1e7293; -} -.article-footer { - font-size: 0.85em; - line-height: 1.6em; - border-top: 1px solid #ddd; - padding-top: 1.6em; - margin: 0 20px 20px; -} -.article-footer:before, -.article-footer:after { - content: ""; - display: table; -} -.article-footer:after { - clear: both; -} -.article-footer a { - color: #999; - text-decoration: none; -} -.article-footer a:hover { - color: #555; -} -.article-tag-list-item { - float: left; - margin-right: 10px; -} -.article-tag-list-link:before { - content: "#"; -} -.article-comment-link { - float: right; -} -.article-comment-link:before { - content: "\f075"; - font-family: FontAwesome; - padding-right: 8px; -} -.article-share-link { - cursor: pointer; - float: right; - margin-left: 20px; -} -.article-share-link:before { - content: "\f064"; - font-family: FontAwesome; - padding-right: 6px; -} -#article-nav { - position: relative; -} -#article-nav:before, -#article-nav:after { - content: ""; - display: table; -} -#article-nav:after { - clear: both; -} -@media screen and (min-width: 768px) { - #article-nav { - margin: 50px 0; - } - #article-nav:before { - width: 8px; - height: 8px; - position: absolute; - top: 50%; - left: 50%; - margin-top: -4px; - margin-left: -4px; - content: ""; - -webkit-border-radius: 50%; - border-radius: 50%; - background: #ddd; - -webkit-box-shadow: 0 1px 2px #fff; - box-shadow: 0 1px 2px #fff; - } -} -.article-nav-link-wrap { - text-decoration: none; - text-shadow: 0 1px #fff; - color: #999; - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; - margin-top: 50px; - text-align: center; - display: block; -} -.article-nav-link-wrap:hover { - color: #555; -} -@media screen and (min-width: 768px) { - .article-nav-link-wrap { - width: 50%; - margin-top: 0; - } -} -@media screen and (min-width: 768px) { - #article-nav-newer { - float: left; - text-align: right; - padding-right: 20px; - } -} -@media screen and (min-width: 768px) { - #article-nav-older { - float: right; - text-align: left; - padding-left: 20px; - } -} -.article-nav-caption { - text-transform: uppercase; - letter-spacing: 2px; - color: #ddd; - line-height: 1em; - font-weight: bold; -} -#article-nav-newer .article-nav-caption { - margin-right: -2px; -} -.article-nav-title { - font-size: 0.85em; - line-height: 1.6em; - margin-top: 0.5em; -} -.article-share-box { - position: absolute; - display: none; - background: #fff; - -webkit-box-shadow: 1px 2px 10px rgba(0,0,0,0.2); - box-shadow: 1px 2px 10px rgba(0,0,0,0.2); - -webkit-border-radius: 3px; - border-radius: 3px; - margin-left: -145px; - overflow: hidden; - z-index: 1; -} -.article-share-box.on { - display: block; -} -.article-share-input { - width: 100%; - background: none; - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; - font: 14px "Helvetica Neue", Helvetica, Arial, sans-serif; - padding: 0 15px; - color: #555; - outline: none; - border: 1px solid #ddd; - -webkit-border-radius: 3px 3px 0 0; - border-radius: 3px 3px 0 0; - height: 36px; - line-height: 36px; -} -.article-share-links { - background: #eee; -} -.article-share-links:before, -.article-share-links:after { - content: ""; - display: table; -} -.article-share-links:after { - clear: both; -} -.article-share-twitter, -.article-share-facebook, -.article-share-pinterest, -.article-share-google { - width: 50px; - height: 36px; - display: block; - float: left; - position: relative; - color: #999; - text-shadow: 0 1px #fff; -} -.article-share-twitter:before, -.article-share-facebook:before, -.article-share-pinterest:before, -.article-share-google:before { - font-size: 20px; - font-family: FontAwesome; - width: 20px; - height: 20px; - position: absolute; - top: 50%; - left: 50%; - margin-top: -10px; - margin-left: -10px; - text-align: center; -} -.article-share-twitter:hover, -.article-share-facebook:hover, -.article-share-pinterest:hover, -.article-share-google:hover { - color: #fff; -} -.article-share-twitter:before { - content: "\f099"; -} -.article-share-twitter:hover { - background: #00aced; - text-shadow: 0 1px #008abe; -} -.article-share-facebook:before { - content: "\f09a"; -} -.article-share-facebook:hover { - background: #3b5998; - text-shadow: 0 1px #2f477a; -} -.article-share-pinterest:before { - content: "\f0d2"; -} -.article-share-pinterest:hover { - background: #cb2027; - text-shadow: 0 1px #a21a1f; -} -.article-share-google:before { - content: "\f0d5"; -} -.article-share-google:hover { - background: #dd4b39; - text-shadow: 0 1px #be3221; -} -.article-gallery { - background: #000; - position: relative; -} -.article-gallery-photos { - position: relative; - overflow: hidden; -} -.article-gallery-img { - display: none; - max-width: 100%; -} -.article-gallery-img:first-child { - display: block; -} -.article-gallery-img.loaded { - position: absolute; - display: block; -} -.article-gallery-img img { - display: block; - max-width: 100%; - margin: 0 auto; -} -#comments { - background: #fff; - -webkit-box-shadow: 1px 2px 3px #ddd; - box-shadow: 1px 2px 3px #ddd; - padding: 20px; - border: 1px solid #ddd; - -webkit-border-radius: 3px; - border-radius: 3px; - margin: 50px 0; -} -#comments a { - color: #258fb8; -} -.archives-wrap { - margin: 50px 0; -} -.archives:before, -.archives:after { - content: ""; - display: table; -} -.archives:after { - clear: both; -} -.archive-year-wrap { - margin-bottom: 1em; -} -.archives { - -webkit-column-gap: 10px; - -moz-column-gap: 10px; - column-gap: 10px; -} -@media screen and (min-width: 480px) and (max-width: 767px) { - .archives { - -webkit-column-count: 2; - -moz-column-count: 2; - column-count: 2; - } -} -@media screen and (min-width: 768px) { - .archives { - -webkit-column-count: 3; - -moz-column-count: 3; - column-count: 3; - } -} -.archive-article { - -webkit-column-break-inside: avoid; - page-break-inside: avoid; - overflow: hidden; - break-inside: avoid-column; -} -.archive-article-inner { - padding: 10px; - margin-bottom: 15px; -} -.archive-article-title { - text-decoration: none; - font-weight: bold; - color: #555; - -webkit-transition: color 0.2s; - -moz-transition: color 0.2s; - -ms-transition: color 0.2s; - transition: color 0.2s; - line-height: 1.6em; -} -.archive-article-title:hover { - color: #258fb8; -} -.archive-article-footer { - margin-top: 1em; -} -.archive-article-date { - color: #999; - text-decoration: none; - font-size: 0.85em; - line-height: 1em; - margin-bottom: 0.5em; - display: block; -} -#page-nav { - margin: 50px auto; - background: #fff; - -webkit-box-shadow: 1px 2px 3px #ddd; - box-shadow: 1px 2px 3px #ddd; - border: 1px solid #ddd; - -webkit-border-radius: 3px; - border-radius: 3px; - text-align: center; - color: #999; - overflow: hidden; -} -#page-nav:before, -#page-nav:after { - content: ""; - display: table; -} -#page-nav:after { - clear: both; -} -#page-nav a, -#page-nav span { - padding: 10px 20px; - line-height: 1; - height: 2ex; -} -#page-nav a { - color: #999; - text-decoration: none; -} -#page-nav a:hover { - background: #999; - color: #fff; -} -#page-nav .prev { - float: left; -} -#page-nav .next { - float: right; -} -#page-nav .page-number { - display: inline-block; -} -@media screen and (max-width: 479px) { - #page-nav .page-number { - display: none; - } -} -#page-nav .current { - color: #555; - font-weight: bold; -} -#page-nav .space { - color: #ddd; -} -#footer { - background: #262a30; - padding: 50px 0; - border-top: 1px solid #ddd; - color: #999; -} -#footer a { - color: #258fb8; - text-decoration: none; -} -#footer a:hover { - text-decoration: underline; -} -#footer-info { - line-height: 1.6em; - font-size: 0.85em; -} -.article-entry pre, -.article-entry .highlight { - background: #2d2d2d; - margin: 0 -20px; - padding: 15px 20px; - border-style: solid; - border-color: #ddd; - border-width: 1px 0; - overflow: auto; - color: #ccc; - line-height: 22.400000000000002px; -} -.article-entry .highlight .gutter pre, -.article-entry .gist .gist-file .gist-data .line-numbers { - color: #666; - font-size: 0.85em; -} -.article-entry pre, -.article-entry code { - font-family: "Source Code Pro", Consolas, Monaco, Menlo, Consolas, monospace; -} -.article-entry code { - background: #eee; - text-shadow: 0 1px #fff; - padding: 0 0.3em; -} -.article-entry pre code { - background: none; - text-shadow: none; - padding: 0; -} -.article-entry .highlight pre { - border: none; - margin: 0; - padding: 0; -} -.article-entry .highlight table { - margin: 0; - width: auto; -} -.article-entry .highlight td { - border: none; - padding: 0; -} -.article-entry .highlight figcaption { - font-size: 0.85em; - color: #999; - line-height: 1em; - margin-bottom: 1em; -} -.article-entry .highlight figcaption:before, -.article-entry .highlight figcaption:after { - content: ""; - display: table; -} -.article-entry .highlight figcaption:after { - clear: both; -} -.article-entry .highlight figcaption a { - float: right; -} -.article-entry .highlight .gutter pre { - text-align: right; - padding-right: 20px; -} -.article-entry .highlight .line { - height: 22.400000000000002px; -} -.article-entry .gist { - margin: 0 -20px; - border-style: solid; - border-color: #ddd; - border-width: 1px 0; - background: #2d2d2d; - padding: 15px 20px 15px 0; -} -.article-entry .gist .gist-file { - border: none; - font-family: "Source Code Pro", Consolas, Monaco, Menlo, Consolas, monospace; - margin: 0; -} -.article-entry .gist .gist-file .gist-data { - background: none; - border: none; -} -.article-entry .gist .gist-file .gist-data .line-numbers { - background: none; - border: none; - padding: 0 20px 0 0; -} -.article-entry .gist .gist-file .gist-data .line-data { - padding: 0 !important; -} -.article-entry .gist .gist-file .highlight { - margin: 0; - padding: 0; - border: none; -} -.article-entry .gist .gist-file .gist-meta { - background: #2d2d2d; - color: #999; - font: 0.85em "Helvetica Neue", Helvetica, Arial, sans-serif; - text-shadow: 0 0; - padding: 0; - margin-top: 1em; - margin-left: 20px; -} -.article-entry .gist .gist-file .gist-meta a { - color: #258fb8; - font-weight: normal; -} -.article-entry .gist .gist-file .gist-meta a:hover { - text-decoration: underline; -} -pre .comment, -pre .title { - color: #999; -} -pre .variable, -pre .attribute, -pre .tag, -pre .regexp, -pre .ruby .constant, -pre .xml .tag .title, -pre .xml .pi, -pre .xml .doctype, -pre .html .doctype, -pre .css .id, -pre .css .class, -pre .css .pseudo { - color: #f2777a; -} -pre .number, -pre .preprocessor, -pre .built_in, -pre .literal, -pre .params, -pre .constant { - color: #f99157; -} -pre .class, -pre .ruby .class .title, -pre .css .rules .attribute { - color: #9c9; -} -pre .string, -pre .value, -pre .inheritance, -pre .header, -pre .ruby .symbol, -pre .xml .cdata { - color: #9c9; -} -pre .css .hexcolor { - color: #6cc; -} -pre .function, -pre .python .decorator, -pre .python .title, -pre .ruby .function .title, -pre .ruby .title .keyword, -pre .perl .sub, -pre .javascript .title, -pre .coffeescript .title { - color: #69c; -} -pre .keyword, -pre .javascript .function { - color: #c9c; -} -@media screen and (max-width: 479px) { - #mobile-nav { - position: absolute; - top: 0; - left: 0; - width: 280px; - height: 100%; - background: #191919; - border-right: 1px solid #fff; - } -} -@media screen and (max-width: 479px) { - .mobile-nav-link { - display: block; - color: #999; - text-decoration: none; - padding: 15px 20px; - font-weight: bold; - } - .mobile-nav-link:hover { - color: #fff; - } -} -@media screen and (min-width: 768px) { - #sidebar { - display: inline; - float: left; - width: 23.333333333333332%; - margin: 0 0.833333333333333%; - } -} -.widget-wrap { - margin: 50px 0; -} -.widget { - color: #777; - text-shadow: 0 1px #fff; - background: #ddd; - -webkit-box-shadow: 0 -1px 4px #ccc inset; - box-shadow: 0 -1px 4px #ccc inset; - border: 1px solid #ccc; - padding: 15px; - -webkit-border-radius: 3px; - border-radius: 3px; -} -.widget a { - color: #258fb8; - text-decoration: none; -} -.widget a:hover { - text-decoration: underline; -} -.widget ul ul, -.widget ol ul, -.widget dl ul, -.widget ul ol, -.widget ol ol, -.widget dl ol, -.widget ul dl, -.widget ol dl, -.widget dl dl { - margin-left: 15px; - list-style: disc; -} -.widget { - line-height: 1.6em; - word-wrap: break-word; - font-size: 0.9em; -} -.widget ul, -.widget ol { - list-style: none; - margin: 0; -} -.widget ul ul, -.widget ol ul, -.widget ul ol, -.widget ol ol { - margin: 0 20px; -} -.widget ul ul, -.widget ol ul { - list-style: disc; -} -.widget ul ol, -.widget ol ol { - list-style: decimal; -} -.category-list-count, -.tag-list-count, -.archive-list-count { - padding-left: 5px; - color: #999; - font-size: 0.85em; -} -.category-list-count:before, -.tag-list-count:before, -.archive-list-count:before { - content: "("; -} -.category-list-count:after, -.tag-list-count:after, -.archive-list-count:after { - content: ")"; -} -.tagcloud a { - margin-right: 5px; - display: inline-block; -} diff --git a/index.html b/index.html deleted file mode 100644 index 01954e4..0000000 --- a/index.html +++ /dev/null @@ -1,502 +0,0 @@ - - - - - - Wang Rui's Blog - - - - - - - - - - - - - - - - - - - - - - -
-
- -
-
- - - - - - - - - -
- -
- - -
- - -

- NSInputStream 和 NSOutputStream -

- - -
- -
- -

对于 NSInputStream 和 NSOutputStream 一直没怎么搞清楚,今天抽一些时间在此记录一下!

-

NSInputStream 与 NSOutputStream 都继承于 NSStream, NSStream 是一个抽象的基类, 规定了Stream共有的一些行为…

- -

- Read More -

- - -
- -
- -
- - - - - - - -
- -
- - -
- - -

- id vs instancetype -

- - -
- -
- -

不知道从什么时候开始IOS的SDK里多了一个叫instancetype的东西,顾名思义返回的就是一个实例对象,所以也没有深究。 但是这玩意和以前的id有什么区别呢,突然比较好奇。 上网查看了下相关的资料,自己也做了下测试,在这里记录一下。
- -

- Read More -

- - -
- -
- -
- - - -
- -
- - -
- - -

- Octopress 配置 -

- - -
- -
- -

在我的配置过程中出现很多问题,比如说tag-cloud不能显示,中文不能支持,还有添加评论、日历的插件没有搞上去。这个真的太考验动手能力了……..
说实话,我更喜欢博客园写博客。 以后慢慢的熟练吧! 下面转载几篇比较好的配置教程:
- -

- Read More -

- - -
- -
- -
- - - -
- -
- - -
- - -

- Octopress 第一篇博客 -

- - -
- -
- -

这是搭建好Octopress写的第一篇博客,搭建过程中遇到了不少麻烦,但最后还是成功搭建出来了,感觉还不错。 还有很多东
西需要琢磨,比如主题、markdown语法、博客写作….总之,需要花时间折腾一下才行。

- - -
- -
- -
- - - - -
- - - -
-
- -
- -
-
- - -
- - - - - - - - - - - - - - -
- - \ No newline at end of file diff --git a/package.json b/package.json new file mode 100644 index 0000000..db47a5b --- /dev/null +++ b/package.json @@ -0,0 +1,19 @@ +{ + "name": "hexo-site", + "version": "0.0.0", + "private": true, + "hexo": { + "version": "3.1.1" + }, + "dependencies": { + "hexo": "^3.1.0", + "hexo-generator-archive": "^0.1.2", + "hexo-generator-category": "^0.1.2", + "hexo-generator-index": "^0.1.2", + "hexo-generator-tag": "^0.1.1", + "hexo-renderer-ejs": "^0.1.0", + "hexo-renderer-stylus": "^0.3.0", + "hexo-renderer-marked": "^0.2.4", + "hexo-server": "^0.1.2" + } +} \ No newline at end of file diff --git a/scaffolds/draft.md b/scaffolds/draft.md new file mode 100644 index 0000000..45b1bb7 --- /dev/null +++ b/scaffolds/draft.md @@ -0,0 +1,3 @@ +title: {{ title }} +tags: +--- diff --git a/scaffolds/page.md b/scaffolds/page.md new file mode 100644 index 0000000..f484b76 --- /dev/null +++ b/scaffolds/page.md @@ -0,0 +1,3 @@ +title: {{ title }} +date: {{ date }} +--- diff --git a/scaffolds/post.md b/scaffolds/post.md new file mode 100644 index 0000000..c590d7a --- /dev/null +++ b/scaffolds/post.md @@ -0,0 +1,4 @@ +title: {{ title }} +date: {{ date }} +tags: +--- diff --git a/source/_posts/2013-05-12-first-blog.markdown b/source/_posts/2013-05-12-first-blog.markdown new file mode 100755 index 0000000..2d3be2f --- /dev/null +++ b/source/_posts/2013-05-12-first-blog.markdown @@ -0,0 +1,14 @@ +--- +layout: post +title: "Octopress 第一篇博客" +date: 2013-05-12 23:29 +comments: true +categories: tools +tags: [octopress] +--- + +这是搭建好Octopress写的第一篇博客,搭建过程中遇到了不少麻烦,但最后还是成功搭建出来了,感觉还不错。 还有很多东 +西需要琢磨,比如主题、markdown语法、博客写作....总之,需要花时间折腾一下才行。 + + + diff --git a/source/_posts/2013-05-14-octopress-pei-zhi.markdown b/source/_posts/2013-05-14-octopress-pei-zhi.markdown new file mode 100755 index 0000000..b15acec --- /dev/null +++ b/source/_posts/2013-05-14-octopress-pei-zhi.markdown @@ -0,0 +1,21 @@ +--- +layout: post +title: "Octopress 配置" +date: 2013-05-14 00:13 +comments: true +categories: tools +tags: octopress +--- +在我的配置过程中出现很多问题,比如说tag-cloud不能显示,中文不能支持,还有添加评论、日历的插件没有搞上去。这个真的太考验动手能力了........ +说实话,我更喜欢博客园写博客。 以后慢慢的熟练吧! 下面转载几篇比较好的配置教程: + + + * [Octopress主题改造](http://shanewfx.github.io/blog/2012/08/13/improve-blog-theme/) + + * [定制Octopress](http://biaobiaoqi.me/blog/2013/07/10/decorate-octopress/) + + * [为octopress添加分类(category)列表](http://codemacro.com/2012/07/18/add-category-list-to-octopress/) + + * [为octopress添加tag Cloud](http://codemacro.com/2012/07/18/add-tag-to-octopress/) + + * [为octopress每篇文章添加一个文章信息](http://codemacro.com/2012/07/26/post-footer-plugin-for-octopress/) \ No newline at end of file diff --git a/source/_posts/2014-01-13-id-vs-instance.markdown b/source/_posts/2014-01-13-id-vs-instance.markdown new file mode 100644 index 0000000..625a4b5 --- /dev/null +++ b/source/_posts/2014-01-13-id-vs-instance.markdown @@ -0,0 +1,36 @@ +--- +layout: post +title: "id vs instancetype" +date: 2014-01-13 09:35:13 +0800 +comments: true +categories: iOS +tags: language +--- + +不知道从什么时候开始IOS的SDK里多了一个叫_instancetype_的东西,顾名思义返回的就是一个实例对象,所以也没有深究。 但是这玩意和以前的id有什么区别呢,突然比较好奇。 上网查看了下相关的资料,自己也做了下测试,在这里记录一下。 + + + * 首先一个很重要的区别,id可以作为函数的参数和返回值,而instancetyp则只能作为返回值; + + * 其他区别,我用简单的话来概括就是: + + 如果返回的是instancetype,那么编译器是知道你返回的具体对象是什么类型,当你向这个实例发送不属于这个类的消息时,编译器则会报错。 + + {% img /images/instance_err_1.png %} + + 而id则是向它可以发送任何消息的,所以编译器不会报错,编译能通过 + + {% img /images/instance_normal.png %} + + 但是有一种特殊情况: 我们知道- (id)init 这个方法返回的是id,但是当你用这个方法生成的实例,向其发送不属于这个类的消息时,编译器也会报错。 + + {% img /images/instance_err_2.png %} + + 这是为什么呢,不是可以向id发送任意消息吗? 原来这是因为编译器默认的初始化方法返回的是instancetype,你看着是id,但编译器实现时就是给你返回的是instancetype! 当我们用类方法返回的id,编译器才会真正的当成id处理。 + +###总结 + instancetype的出现,可以避免程序在运行时向某个对象发送不是它的消息引起崩溃,因为编译的时候就不让你通过。所以当你返回的对象确定为这个类的实例时,尽量使用instancetpye吧。 比如经常使用的单例模式,则可声明返回的为instancetype。 + 仅仅是自己的理解,如有不对之处,请大家指正! + +###参考文章 +[_instancetype_](http://nshipster.com/instancetype/) \ No newline at end of file diff --git a/source/_posts/2014-01-22-mantle-use.markdown b/source/_posts/2014-01-22-mantle-use.markdown new file mode 100644 index 0000000..28f69df --- /dev/null +++ b/source/_posts/2014-01-22-mantle-use.markdown @@ -0,0 +1,213 @@ +--- +layout: post +title: "Mantle 初步使用" +date: 2014-01-22 13:54:10 +0800 +comments: true +categories: iOS +--- + +最近接触到了Mantle这个东西,感觉很不错,在此与各位分享一下。 + + +###前言 +在开发的过程中,我们常常会从网络获取数据,而数据通常又为JSON格式。 这时比较常见的做法是把JSON数据转为Model对象,这样我们可以从Model对象的属性读取数据。 但是常常会面临如下一些问题: + +* 每次都要用 `-initWithDictionarty:(NSDictionary *)dict` 等类似的方法初始化,把JSON数据里的值一个一个的赋值给Modeld对象的属性,深深的感觉到自己在做重复的工作,有木有! + +* 当你需要的某个数据在JSON字典数据里层次很深时,需要不断的使用 `[[obj objectForKey:@"key"] objectAtIndex:index] objectForKey:@""]...` 这样很长的代码,是不是感觉很不爽! + +* 服务器给你返回的数据不是你期望的,例如:有些时候你需要的是一个NSString类型,但给你的是一个NSNumber。 有时你需要的是一个NSDate类型,但给你的是一个NSString类型,你还不得不去做一些判断,写一些转换的代码。 还有一种严重的情况,由于服务器故障,给你返回了一个NSNull,如果你没有做一些判断处理,那么这时你的程序崩溃的几率很大! + +* 如何从这个Model对象,再还原成之前的JSON字典数据? 其次,你想把这个Model对象存储下来的话,那么你不得不自己去处理NSCoding协议等一些烦人的问题,又是一些重复工作! + +有没有办法可以很优雅的解决这些问题呢,这就是今天要说的Mantle框架。 + +###什么是Mantle? +Mantle是github的工程师们弄出来的东西,[github主页在此](https://github.com/MantleFramework/Mantle), +引用如下: +{% blockquote %} +Mantle makes it easy to write a simple model layer for your Cocoa or Cocoa Touch application. +{% endblockquote %} + +###使用 +下面就来说一下怎么使用,首先新建一个空的工程,把Mantle的代码下载下来,拖入你的工程。 我建议使用[CocoaPods](http://cocoapods.org)来管理第三方库,反正我就是这样干的,非常简单方便。 浏览一下框架的目录,大概如下图所示: + +{%img /images/Mantle-01.png %} + +居然这么多文件! 不要害怕,我们常用到的就是`MTLJSONAdapter`和`MTLModle`而已。 `MTLModel`是一个抽象类,它帮我们做了很多工作,比如解决前言里提出的一些问题。 我们要建的Model类应该继承于它,此外你的继承类一定还要实现`MTLJSONSerializing`协议。 `MTLJSONAdapter`则是帮我们把JSON数据绑定到Model的属性里,当然,你不用担心会出现`NSNull`的情况,因为转换后它会自动设置成`nil`; + +我们新建一个继承 `MTLModel` 的类,叫做 `TestDataModel`。 我们将从[这个地址](http://api.openweathermap.org/data/2.5/weather?lat=37.785834&lon=-122.406417&units=imperial)获取测试数据。 现在把想要的数据声明到头文件里 + +``` objc + +//TestDataModel.h +#import + +@interface TestDataModel : MTLModel + +@property (nonatomic, strong) NSDate *date; +@property (nonatomic, strong) NSNumber *humidity; +@property (nonatomic, strong) NSNumber *temperature; +@property (nonatomic, strong) NSNumber *tempHigh; +@property (nonatomic, strong) NSNumber *tempLow; +@property (nonatomic, strong) NSString *locationName; +@property (nonatomic, strong) NSDate *sunrise; +@property (nonatomic, strong) NSDate *sunset; +@property (nonatomic, strong) NSString *conditionDescription; +@property (nonatomic, strong) NSString *condition; +@property (nonatomic, strong) NSNumber *windBearing; +@property (nonatomic, strong) NSNumber *windSpeed; + +@end + + +``` + +在`TestDataModel.m`文件里,实现`MTLJSONSerializing`协议里的`+ (NSDictionary *)JSONKeyPathsByPropertyKey` 方法。 + + +``` objc + +//TestDataModel.m +#import "TestDataModel.h" + +@implementation TestDataModel + ++ (NSDictionary *)JSONKeyPathsByPropertyKey { + return @{ + @"date": @"dt", //将JSON字典里dt键对应的值,赋值给date属性 + @"locationName": @"name", + @"humidity": @"main.humidity", + @"temperature": @"main.temp",//这个点是什么意思呢,表示将main键对应的子字典里, + //temp键对应的值赋给temperature属性。 + //我们不用再写 objectForKey]objectForKey]..这种代码了。 + //注意了:当main键对应的是数组时,main.temp返回的 + //为所有temp键对应值的数组合集 + + @"tempHigh": @"main.temp_max", + @"tempLow": @"main.temp_min", + @"sunrise": @"sys.sunrise", + @"sunset": @"sys.sunset", + @"conditionDescription": @"weather.description", + @"condition": @"weather.main", + @"icon": @"weather.icon", + @"windBearing": @"wind.deg", + @"windSpeed": @"wind.speed", + }; +} + +``` + +解释都在注释里。 Model类到此可以用了。 现在我们在`AppDelegate.m`里,编写相关的测试代码 + +``` objc +- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions +{ + NSURL *url = [NSURL URLWithString:@"http://api.openweathermap.org/data/2.5/weather?lat=37.785834&lon=-122.406417&units=imperial"]; + [NSURLConnection sendAsynchronousRequest:[NSURLRequest requestWithURL:url] + queue:[NSOperationQueue mainQueue] + completionHandler:^(NSURLResponse* response, NSData* data, NSError* connectionError){ + if (!connectionError) { + NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:data + options:NSJSONReadingMutableContainers + error:nil]; + //将JSON数据和Model的属性进行绑定 + TestDataModel *model = [MTLJSONAdapter modelOfClass:[TestDataModel class] + fromJSONDictionary:dict + error:nil]; + NSLog(@"%@",model); + } + }]; + +} + +``` +设置断点到15行,控制台显示如下图: + +{%img /images/Mantle-02.png %} + +可以看到所有属性值均已设置好了。 强大吧! 等等...这好像和我们期望的类型不太一样,我们声明的date是一个NSDate型,但这里却是NSNumber。JSON数据里解析出来的就是NSNumber,那要怎么转化为我们期望的NSDate呢? Mantle为我们提供了强大的转换机制。 继续回到`TestDataModel.m`文件里。添加如下代码: + +``` objc +//TestDataModel.m + ++ (NSValueTransformer *)dateJSONTransformer { + return [MTLValueTransformer reversibleTransformerWithForwardBlock:^(NSNumber *dateNum) { + return [NSDate dateWithTimeIntervalSince1970:dateNum.floatValue]; + } reverseBlock:^(NSDate *date) { + return [NSString stringWithFormat:@"%f",[date timeIntervalSince1970]]; + }]; +} +``` +再次运行,控制台结果如下图: + +{%img /images/Mantle-03.png %} + +看见了吗,date已经成功转换为NSDate了! 原来,上面的代码是要告知Mantle,赋值时要先进行转换,原始JSON里是一个NSNumber,现在转换为一个NSDate并返回。 其他属性需要转换的都可以这样做,方法命名规则是 `属性JSONTransformer`,那么在对这个属性进行赋值时就会调用这个方法先进行转换。当JSON数据里有NSNull的类型时,我们不用做任何处理,会自动将该属性置为nil; + +那reverseBlock是干什么的呢? 当要把Model转换回JSON数据时,如果设置了返回值,那么会将NSDate转回NSNumber返回JSON数据。 我们可以调用 `MTLJSONAdapter`的 + +``` objc ++ (NSDictionary *)JSONDictionaryFromModel:(MTLModel *)model; +``` + +方法将一个Model实例转回JSON数据。 + + +####Model对象的存储: +由于MTLModel已经帮我们实现了NSCoding协议, 要把一个Model对象存储到本地就相当简单了,只需一行代码: + +``` objc +[NSKeyedArchiver archiveRootObject:model toFile:path]; + +``` + +解档时同样简单: + +``` objc +TestDataModel *unachiveModel = [NSKeyedUnarchiver unarchiveObjectWithFile:path]; +``` + + Mantle还可以结合CoreData使用,这里不说了。 至此,Mantle的简单使用就介绍完了! 如有什么不对之处,请各位谅解和指正! + + + +###原理 + +没有深入研究源码,准备抽时间仔细研究一把。 大致看了下,Mantle主要使用了一些Runtime的东西,获取到所有propertiy属性进行绑定。 代码看起来有种不明觉厉的感觉,不得不感叹github上的牛人真多! 想深入研究的同学可以多看下源码! + + +###参考文章 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/source/_posts/2014-09-11-nsinputstream-and-nsoutputstream.markdown b/source/_posts/2014-09-11-nsinputstream-and-nsoutputstream.markdown new file mode 100644 index 0000000..27ff289 --- /dev/null +++ b/source/_posts/2014-09-11-nsinputstream-and-nsoutputstream.markdown @@ -0,0 +1,223 @@ +--- +layout: post +title: "NSInputStream 和 NSOutputStream" +date: 2014-09-11 21:03:56 +0800 +comments: true +categories: iOS +--- + +对于 NSInputStream 和 NSOutputStream 一直没怎么搞清楚,今天抽一些时间在此记录一下! + +NSInputStream 与 NSOutputStream 都继承于 NSStream, NSStream 是一个抽象的基类, 规定了Stream共有的一些行为... + + + +###什么是Stream + +Stream翻译成为流,它是对我们读写文件的一个抽象。 你可以这样想象,当你读文件和写文件的时候,文件的内容就像水流一样哗哗的 +像你流过来或者流给别人,这样岂不是很爽。 而Stream就帮我们做了这样的事情, 实际上,它是把文件的内容,一小段一小段的读出或 +写入,来到达这样的效果 + +###NSStream + +NSStream 是Cocoa平台下对流这个概念的实现类, NSInputStream 和 NSOutputStream 则是它的两个子类,分别对应了读文件和 +写文件。 + + +###NSInputStream + +NSInputStream 对应的是读文件,所以要记住它是要将文件的内容读到内存(你声明的一段buffer)里, 下面一段是测试代码 + + +``` objc + +- (void)doTestInputStream { + NSString *path = @"/Users/usr/Desktop/stream.txt"; + + NSInputStream *readStream = [[NSInputStream alloc]initWithFileAtPath:path]; + [readStream setDelegate:self]; + + [readStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes]; + [readStream open]; //调用open开始读文件 +} + +- (void)stream:(NSStream *)aStream handleEvent:(NSStreamEvent)eventCode { + switch (eventCode) { + case NSStreamEventHasBytesAvailable:{ + + uint8_t buf[1024]; + + NSInputStream *reads = (NSInputStream *)aStream; + NSInteger blength = [reads read:buf maxLength:sizeof(buf)]; //把流的数据放入buffer + NSData *data = [NSData dataWithBytes:(void *)buf length:blength]; + + NSString *string = [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding]; + NSLog(@"%@",string); + } + break; + + + //错误和无事件处理 + case NSStreamEventErrorOccurred:{ + + } + break; + case NSStreamEventNone: + break; + + //打开完成 + case NSStreamEventOpenCompleted: { + NSLog(@"NSStreamEventOpenCompleted"); + } + break; + + default: + break; + } +} + +@end + +``` + +###NSOutputStream + +NSOutputStream 对应的是写文件,它是要将已存在的内存(buffer)里的数据写入文件, 下面同样一段是测试代码 + +``` objc + +- (NSData *)dataWillWrite { + static NSData *data = nil; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + data = [NSData dataWithContentsOfFile:@"/Users/usr/Desktop/stream.txt"]; + }); + + return data; +} + +- (void)doTestOutputStream { + NSString *path = @"/Users/usr/Desktop/stream-write.txt"; + + NSOutputStream *writeStream = [[NSOutputStream alloc] initToFileAtPath:path append:YES]; + [writeStream setDelegate:self]; + + [writeStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes]; + [writeStream open]; +} + +- (void)stream:(NSStream *)aStream handleEvent:(NSStreamEvent)eventCode { + switch (eventCode) { + case NSStreamEventHasSpaceAvailable: { + + NSInteger bufSize = 5; + uint8_t buf[bufSize]; + + if (self.location + bufSize > [self dataWillWrite].length) { + [[self dataWillWrite] getBytes:buf + range:NSMakeRange(self.location, self.location + bufSize - [self dataWillWrite].length)]; + } + else { + [[self dataWillWrite] getBytes:buf range:NSMakeRange(self.location, bufSize)]; + } + + NSOutputStream *writeStream = (NSOutputStream *)aStream; + [writeStream write:buf maxLength:sizeof(buf)]; //把buffer里的数据,写入文件 + + self.location += bufSize; + if (self.location >= [[self dataWillWrite] length] ) { //写完后关闭流 + [aStream close]; + } + + } + break; + + case NSStreamEventEndEncountered: { + [aStream close]; + } + break; + + //错误和无事件处理 + case NSStreamEventErrorOccurred:{ + + } + break; + case NSStreamEventNone: + break; + + //打开完成 + case NSStreamEventOpenCompleted: { + NSLog(@"NSStreamEventOpenCompleted"); + + + } + break; + + default: + break; + } +} +``` + +### 用途 + +NSInputStream 和 NSOutputStream 常用与网络传输中,比如要将一个很大的文件传送给服务器,那么NSInputStream这时候是 +很好的选择, 我们可以查看到 NSURLRequest 有一个属性叫HTTPBodyStream, 这时只要设置好一个NSInputStream的实例就可以 +了,最大的好处就是可以节省我们很多的内存。 + +另外要说明的是,NSInputStream 和 NSOutputStream其实是对 CoreFoundation 层对应的CFReadStreamRef 和 CFWriteStreamRef +的高层抽象。在使用CFNetwork时,常常会使用到CFReadStreamRef 与 CFWriteStreamRef。 下面是一段相关代码 + +``` objc + + // Keep a reference to self to use for controller callbacks + // + CFStreamClientContext ctx = {0, (__bridge void *)(self), NULL, NULL, NULL}; + + // Get callbacks for stream data, stream end, and any errors + // + CFOptionFlags registeredEvents = (kCFStreamEventHasBytesAvailable | kCFStreamEventEndEncountered | kCFStreamEventErrorOccurred); + + // Create a read-only socket + // + CFReadStreamRef readStream; + CFStreamCreatePairWithSocketToHost(kCFAllocatorDefault, (__bridge CFStringRef)host, (UInt32)port, &readStream, NULL); + + // Schedule the stream on the run loop to enable callbacks + // + if (CFReadStreamSetClient(readStream, registeredEvents, socketCallback, &ctx)) { + CFReadStreamScheduleWithRunLoop(readStream, CFRunLoopGetCurrent(), kCFRunLoopCommonModes); + + } + else { + [self networkFailedWithErrorMessage:@"Failed to assign callback method"]; + return; + } + + // Open the stream for reading + // + if (CFReadStreamOpen(readStream) == NO) { + [self networkFailedWithErrorMessage:@"Failed to open read stream"]; + + return; + } + + CFErrorRef error = CFReadStreamCopyError(readStream); + if (error != NULL) { + if (CFErrorGetCode(error) != 0) { + NSString * errorInfo = [NSString stringWithFormat:@"Failed to connect stream; error '%@' (code %ld)", (__bridge NSString*)CFErrorGetDomain(error), CFErrorGetCode(error)]; + [self networkFailedWithErrorMessage:errorInfo]; + } + + CFRelease(error); + + return; + } +``` + + + + + + + diff --git a/source/_posts/2014-09-12-clang-compile-arm-file.markdown b/source/_posts/2014-09-12-clang-compile-arm-file.markdown new file mode 100644 index 0000000..5b4aa70 --- /dev/null +++ b/source/_posts/2014-09-12-clang-compile-arm-file.markdown @@ -0,0 +1,53 @@ +--- +layout: post +title: "Mac上用 clang 简单交叉编译arm架构的文件" +date: 2014-09-12 09:58:38 +0800 +comments: true +categories: iOS +--- + +在Mac上简单的编译出一个可以在 IOS 上运行的 hello world 程序: + + + +* 写一个简单的hello world程序,保存到桌面或者其他地方 + +* 终端里cd 到刚才保存的路径 + +* 运行命令: + +``` objc + +// -arch 表示要编译的架构 这里为armv7. +// -isysroot 指定头文件的根路径 +$ clang -arch armv7 -o hello hello.c -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS7.1.sdk + +//也可以使用xcrun +$ xcrun -sdk iphoneos clang -arch armv7 -o hello hello.c //xcrun -sdk 会使用最新的sdk去编译 + +``` + +* 使用file命令查看编译出来的文件是什么架构 + + +``` objc + +$ file hello //output: 'hello: Mach-O executable arm' + +``` + +* scp 到越狱ios设备运行 + +``` objc + +$ ./hello + +``` + +成功输出 hello world + + + + + + diff --git a/source/_posts/2015-03-08-toll-free-bridging.markdown b/source/_posts/2015-03-08-toll-free-bridging.markdown new file mode 100644 index 0000000..5982a73 --- /dev/null +++ b/source/_posts/2015-03-08-toll-free-bridging.markdown @@ -0,0 +1,66 @@ +--- +layout: post +title: "Toll Free Bridging 的秘密" +date: 2015-03-08 19:07:46 +0800 +comments: true +categories: iOS +tags: briding +--- + +Toll free briding 是用于 Foundation对象和Core Foundation对象间无缝转换的一种方法。首先,我们来看看下面代码: + +``` objc + + CFStringRef cfStr = SomeFunctionThatReturnsCFString(); + NSUInteger length = [(NSString *)cfStr length]; + + NSString *nsStr = [self someString]; + CFIndex length = CFStringGetLength((CFStringRef)nsStr); + +``` + +我们可以将一个 `CFStringRef` 类型的变量通过指针转换为 `NSString *` 类型, 然后直接当作NSString 使用, 向其发送消息。 +同时,我们也可以将 `NSString *`通过指针转换为 `CFStringRef`, 即可当作CFStringRef,对于 CFStringRef 申明的C层级的 +API 均能使用。这便是官方所说得 Toll free briding。 + +那么这一切是如何做到的,内部发生了什么? + +###CF 转为 OBJC +首先,我们来看看CF对象是怎样转为OBJC对象的。 这个方向的转换比较简单。 在OBJC的类里,绝大多数能进行bridging的类都是一层抽象封装,叫做类族。如`NSString`, 我们在得到真正的实例时是它的一个私有子类`NSCFString`。 而`CFStringRef` 和 `NSCFString` 对象具有相同的内存布局, `CFStringRef` 的前4个字节也是一个 `isa` 指针 +,指向 `NSCFString` 类。 由OBJC的消息发送机制我们可以知道,这时候,对其发送OBJC的消息,和对OBJC的对应对象发送消息是一模一样的! + +###OBJC 转为 CF +还以`NSString`为列。上面我们说了:`CFStringRef` 和 `NSCFString` 对象具有相同的内存布局。 这时候,你可能要说了,既然是 +相同的内存布局,直接作指针转换就好了! OBJC对象即可当作CF对象! 可是,有一些情况比较例外。如果我们写了一个类,继承于 +`NSString`, 重写了 `length` 方法。 那么这时候,这个对象则和 `CFStringRef` 不再具有相同的内存布局,它们的`isa`指针指向不同的 +类了。 但是这种情况我们任然是可以作bridging的。这又是怎么办到的? + +CF在他的API里,都做了一个OBJC方法名的映射,如 `CFStringGetLength`: + +``` objc + + CFIndex CFStringGetLength(CFStringRef str) { + + CF_OBJC_FUNCDISPATCH0(__kCFStringTypeID, CFIndex, str, "length"); + + __CFAssertIsString(str); + return __CFStrLength(str); +} + +``` + +`CFStringGetLength` 映射了 `NSString` 的 `length`方法! + +`CF_OBJC_FUNCDISPATCH0` 就是要去判断传进来的str究竟是不是`NSCFString`,如果是则调用 `__CFStrLength` 函数返回。 +如果不是,则向这个对象发送 `length` 消息,并返回。 如果我们传入的是自己继承NSString的对象, +那么这时候则会向这个对象发送`length`消息,重写的方法就得到了调用! + + +注:ARC下的bridging,需要用到`__bridge`, `__bridge_retained`, `__bridge_transfer`修饰符,本文不作讨论。 + + +###参考 +[Friday Q&A 2010-01-22: Toll Free Bridging Internals](https://www.mikeash.com/pyblog/friday-qa-2010-01-22-toll-free-bridging-internals.html) + + + diff --git a/images/Mantle-01.png b/source/images/Mantle-01.png similarity index 100% rename from images/Mantle-01.png rename to source/images/Mantle-01.png diff --git a/images/Mantle-02.png b/source/images/Mantle-02.png similarity index 100% rename from images/Mantle-02.png rename to source/images/Mantle-02.png diff --git a/images/Mantle-03.png b/source/images/Mantle-03.png similarity index 100% rename from images/Mantle-03.png rename to source/images/Mantle-03.png diff --git a/images/bird_32_gray.png b/source/images/bird_32_gray.png similarity index 100% rename from images/bird_32_gray.png rename to source/images/bird_32_gray.png diff --git a/images/bird_32_gray_fail.png b/source/images/bird_32_gray_fail.png similarity index 100% rename from images/bird_32_gray_fail.png rename to source/images/bird_32_gray_fail.png diff --git a/images/code_bg.png b/source/images/code_bg.png similarity index 100% rename from images/code_bg.png rename to source/images/code_bg.png diff --git a/images/dotted-border.png b/source/images/dotted-border.png similarity index 100% rename from images/dotted-border.png rename to source/images/dotted-border.png diff --git a/images/email.png b/source/images/email.png similarity index 100% rename from images/email.png rename to source/images/email.png diff --git a/images/install_octopress_rake_error.png b/source/images/install_octopress_rake_error.png similarity index 100% rename from images/install_octopress_rake_error.png rename to source/images/install_octopress_rake_error.png diff --git a/images/instance_err_1.png b/source/images/instance_err_1.png similarity index 100% rename from images/instance_err_1.png rename to source/images/instance_err_1.png diff --git a/images/instance_err_2.png b/source/images/instance_err_2.png similarity index 100% rename from images/instance_err_2.png rename to source/images/instance_err_2.png diff --git a/images/instance_normal.png b/source/images/instance_normal.png similarity index 100% rename from images/instance_normal.png rename to source/images/instance_normal.png diff --git a/images/line-tile.png b/source/images/line-tile.png similarity index 100% rename from images/line-tile.png rename to source/images/line-tile.png diff --git a/images/noise.png b/source/images/noise.png similarity index 100% rename from images/noise.png rename to source/images/noise.png diff --git a/images/rss.png b/source/images/rss.png similarity index 100% rename from images/rss.png rename to source/images/rss.png diff --git a/images/search.png b/source/images/search.png similarity index 100% rename from images/search.png rename to source/images/search.png diff --git a/tags/briding/index.html b/tags/briding/index.html deleted file mode 100644 index 334d384..0000000 --- a/tags/briding/index.html +++ /dev/null @@ -1,212 +0,0 @@ - - - - - - Tag: briding | Wang Rui's Blog - - - - - - - - - - - - - - - - - - - - - - -
-
- -
-
- - - - - - -
-
- 2015 -
-
- - - - -
- -
- - - -
-
- -
- -
-
- - -
- - - - - - - - - - - - - - -
- - \ No newline at end of file diff --git a/tags/language/index.html b/tags/language/index.html deleted file mode 100644 index 9ab2c24..0000000 --- a/tags/language/index.html +++ /dev/null @@ -1,212 +0,0 @@ - - - - - - Tag: language | Wang Rui's Blog - - - - - - - - - - - - - - - - - - - - - - -
-
- -
-
- - - - - - -
-
- 2014 -
-
- - - - -
- -
- - - -
-
- -
- -
-
- - -
- - - - - - - - - - - - - - -
- - \ No newline at end of file diff --git a/tags/octopress/index.html b/tags/octopress/index.html deleted file mode 100644 index 47d6b61..0000000 --- a/tags/octopress/index.html +++ /dev/null @@ -1,231 +0,0 @@ - - - - - - Tag: octopress | Wang Rui's Blog - - - - - - - - - - - - - - - - - - - - - - -
-
- -
-
- - - - - - -
-
- 2013 -
-
- - - - - - - - -
- -
- - - -
-
- -
- -
-
- - -
- - - - - - - - - - - - - - -
- - \ No newline at end of file diff --git a/themes/landscape/Gruntfile.js b/themes/landscape/Gruntfile.js new file mode 100644 index 0000000..59fd5df --- /dev/null +++ b/themes/landscape/Gruntfile.js @@ -0,0 +1,46 @@ +module.exports = function(grunt){ + grunt.initConfig({ + gitclone: { + fontawesome: { + options: { + repository: 'https://github.com/FortAwesome/Font-Awesome.git', + directory: 'tmp/fontawesome' + }, + }, + fancybox: { + options: { + repository: 'https://github.com/fancyapps/fancyBox.git', + directory: 'tmp/fancybox' + } + } + }, + copy: { + fontawesome: { + expand: true, + cwd: 'tmp/fontawesome/fonts/', + src: ['**'], + dest: 'source/css/fonts/' + }, + fancybox: { + expand: true, + cwd: 'tmp/fancybox/source/', + src: ['**'], + dest: 'source/fancybox/' + } + }, + _clean: { + tmp: ['tmp'], + fontawesome: ['source/css/fonts'], + fancybox: ['source/fancybox'] + } + }); + + require('load-grunt-tasks')(grunt); + + grunt.renameTask('clean', '_clean'); + + grunt.registerTask('fontawesome', ['gitclone:fontawesome', 'copy:fontawesome', '_clean:tmp']); + grunt.registerTask('fancybox', ['gitclone:fancybox', 'copy:fancybox', '_clean:tmp']); + grunt.registerTask('default', ['gitclone', 'copy', '_clean:tmp']); + grunt.registerTask('clean', ['_clean']); +}; \ No newline at end of file diff --git a/themes/landscape/LICENSE b/themes/landscape/LICENSE new file mode 100644 index 0000000..9ce4d32 --- /dev/null +++ b/themes/landscape/LICENSE @@ -0,0 +1,7 @@ +Copyright (c) 2013 Tommy Chen + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/themes/landscape/README.md b/themes/landscape/README.md new file mode 100644 index 0000000..8295fbe --- /dev/null +++ b/themes/landscape/README.md @@ -0,0 +1,111 @@ +# Landscape + +A brand new default theme for [Hexo]. + +- [Preview](http://hexo.io/hexo-theme-landscape/) + +## Installation + +### Install + +``` bash +$ git clone https://github.com/hexojs/hexo-theme-landscape.git themes/landscape +``` + +**Landscape requires Hexo 2.4 and above.** + +### Enable + +Modify `theme` setting in `_config.yml` to `landscape`. + +### Update + +``` bash +cd themes/landscape +git pull +``` + +## Configuration + +``` yml +# Header +menu: + Home: / + Archives: /archives +rss: /atom.xml + +# Content +excerpt_link: Read More +fancybox: true + +# Sidebar +sidebar: right +widgets: +- category +- tag +- tagcloud +- archives +- recent_posts + +# Miscellaneous +google_analytics: +favicon: /favicon.png +twitter: +google_plus: +``` + +- **menu** - Navigation menu +- **rss** - RSS link +- **excerpt_link** - "Read More" link at the bottom of excerpted articles. `false` to hide the link. +- **fancybox** - Enable [Fancybox] +- **sidebar** - Sidebar style. You can choose `left`, `right`, `bottom` or `false`. +- **widgets** - Widgets displaying in sidebar +- **google_analytics** - Google Analytics ID +- **favicon** - Favicon path +- **twitter** - Twiiter ID +- **google_plus** - Google+ ID + +## Features + +### Fancybox + +Landscape uses [Fancybox] to showcase your photos. You can use Markdown syntax or fancybox tag plugin to add your photos. + +``` +![img caption](img url) + +{% fancybox img_url [img_thumbnail] [img_caption] %} +``` + +### Sidebar + +You can put your sidebar in left side, right side or bottom of your site by editing `sidebar` setting. + +Landscape provides 5 built-in widgets: + +- category +- tag +- tagcloud +- archives +- recent_posts + +All of them are enabled by default. You can edit them in `widget` setting. + +## Development + +### Requirements + +- [Grunt] 0.4+ +- Hexo 2.4+ + +### Grunt tasks + +- **default** - Download [Fancybox] and [Font Awesome]. +- **fontawesome** - Only download [Font Awesome]. +- **fancybox** - Only download [Fancybox]. +- **clean** - Clean temporarily files and downloaded files. + +[Hexo]: http://zespia.tw/hexo/ +[Fancybox]: http://fancyapps.com/fancybox/ +[Font Awesome]: http://fontawesome.io/ +[Grunt]: http://gruntjs.com/ diff --git a/themes/landscape/_config.yml b/themes/landscape/_config.yml new file mode 100644 index 0000000..85a1ccf --- /dev/null +++ b/themes/landscape/_config.yml @@ -0,0 +1,26 @@ +# Header +menu: + Home: / + Archives: /archives +rss: /atom.xml + +# Content +excerpt_link: Read More +fancybox: true + +# Sidebar +sidebar: right +widgets: +- category +- tag +- tagcloud +- archive +- recent_posts + +# Miscellaneous +google_analytics: +favicon: /favicon.png +twitter: +google_plus: +fb_admins: +fb_app_id: \ No newline at end of file diff --git a/themes/landscape/layout/_partial/after-footer.ejs b/themes/landscape/layout/_partial/after-footer.ejs new file mode 100644 index 0000000..3bec0ba --- /dev/null +++ b/themes/landscape/layout/_partial/after-footer.ejs @@ -0,0 +1,27 @@ +<% if (config.disqus_shortname){ %> + +<% } %> + + + +<% if (theme.fancybox){ %> + <%- css('fancybox/jquery.fancybox') %> + <%- js('fancybox/jquery.fancybox.pack') %> +<% } %> + +<%- js('js/script') %> + + diff --git a/themes/landscape/layout/_partial/archive-post.ejs b/themes/landscape/layout/_partial/archive-post.ejs new file mode 100644 index 0000000..36f2cc3 --- /dev/null +++ b/themes/landscape/layout/_partial/archive-post.ejs @@ -0,0 +1,8 @@ +
+
+
+ <%- partial('post/date', {class_name: 'archive-article-date', date_format: 'MMM D'}) %> + <%- partial('post/title', {class_name: 'archive-article-title'}) %> +
+
+
\ No newline at end of file diff --git a/themes/landscape/layout/_partial/archive.ejs b/themes/landscape/layout/_partial/archive.ejs new file mode 100644 index 0000000..c2c994b --- /dev/null +++ b/themes/landscape/layout/_partial/archive.ejs @@ -0,0 +1,33 @@ +<% if (pagination == 2){ %> + <% page.posts.each(function(post){ %> + <%- partial('article', {post: post, index: true}) %> + <% }) %> + <% if (page.total > 1){ %> + + <% } %> +<% } else { %> + <% var last; %> + <% page.posts.each(function(post, i){ %> + <% var year = post.date.year(); %> + <% if (last != year){ %> + <% if (last != null){ %> + + <% } %> + <% last = year; %> +
+ +
+ <% } %> + <%- partial('archive-post', {post: post, even: i % 2 == 0}) %> + <% }) %> + <% if (page.posts.length){ %> +
+ <% } %> +<% } %> \ No newline at end of file diff --git a/themes/landscape/layout/_partial/article.ejs b/themes/landscape/layout/_partial/article.ejs new file mode 100644 index 0000000..73c466b --- /dev/null +++ b/themes/landscape/layout/_partial/article.ejs @@ -0,0 +1,57 @@ +
+ +
+ <%- partial('post/gallery') %> + <% if (post.link || post.title){ %> +
+ <%- partial('post/title', {class_name: 'article-title'}) %> +
+ <% } %> +
+ <% if (post.excerpt && index){ %> + <%- post.excerpt %> + <% if (theme.excerpt_link){ %> +

+ <%= theme.excerpt_link %> +

+ <% } %> + <% } else { %> + <%- post.content %> + <% } %> +
+
+ Share + <% if (post.comments && config.disqus_shortname){ %> + Comments + <% } %> + <%- partial('post/tag') %> +
+
+ <% if (!index){ %> + <%- partial('post/nav') %> + <% } %> +
+ + <% if (!index && post.comments && config.duoshuo_shortname){ %> +
+ +
+ + + + +
+ <% } %> \ No newline at end of file diff --git a/themes/landscape/layout/_partial/footer.ejs b/themes/landscape/layout/_partial/footer.ejs new file mode 100644 index 0000000..9c8f9bd --- /dev/null +++ b/themes/landscape/layout/_partial/footer.ejs @@ -0,0 +1,17 @@ +
+ <% if (theme.sidebar === 'bottom'){ %> + <%- partial('_partial/sidebar') %> + <% } %> +
+ +
+
+ + \ No newline at end of file diff --git a/themes/landscape/layout/_partial/google-analytics.ejs b/themes/landscape/layout/_partial/google-analytics.ejs new file mode 100644 index 0000000..84e75f0 --- /dev/null +++ b/themes/landscape/layout/_partial/google-analytics.ejs @@ -0,0 +1,14 @@ +<% if (theme.google_analytics){ %> + + + +<% } %> diff --git a/themes/landscape/layout/_partial/head.ejs b/themes/landscape/layout/_partial/head.ejs new file mode 100644 index 0000000..27f0d07 --- /dev/null +++ b/themes/landscape/layout/_partial/head.ejs @@ -0,0 +1,34 @@ + + + + + <% + var title = page.title; + + if (is_archive()){ + title = 'Archives'; + + if (is_month()){ + title += ': ' + page.year + '/' + page.month; + } else if (is_year()){ + title += ': ' + page.year; + } + } else if (is_category()){ + title = 'Category: ' + page.category; + } else if (is_tag()){ + title = 'Tag: ' + page.tag; + } + %> + <% if (title){ %><%= title %> | <% } %><%= config.title %> + + <%- open_graph({twitter_id: theme.twitter, google_plus: theme.google_plus, fb_admins: theme.fb_admins, fb_app_id: theme.fb_app_id}) %> + <% if (theme.rss){ %> + + <% } %> + <% if (theme.favicon){ %> + + <% } %> + + <%- css('css/style') %> + <%- partial('google-analytics') %> + \ No newline at end of file diff --git a/themes/landscape/layout/_partial/header.ejs b/themes/landscape/layout/_partial/header.ejs new file mode 100644 index 0000000..d536d10 --- /dev/null +++ b/themes/landscape/layout/_partial/header.ejs @@ -0,0 +1,32 @@ + \ No newline at end of file diff --git a/themes/landscape/layout/_partial/mobile-nav.ejs b/themes/landscape/layout/_partial/mobile-nav.ejs new file mode 100644 index 0000000..7c1d2af --- /dev/null +++ b/themes/landscape/layout/_partial/mobile-nav.ejs @@ -0,0 +1,5 @@ + \ No newline at end of file diff --git a/themes/landscape/layout/_partial/post/category.ejs b/themes/landscape/layout/_partial/post/category.ejs new file mode 100644 index 0000000..db2ed48 --- /dev/null +++ b/themes/landscape/layout/_partial/post/category.ejs @@ -0,0 +1,10 @@ +<% if (post.categories && post.categories.length){ %> + +<% } %> \ No newline at end of file diff --git a/themes/landscape/layout/_partial/post/date.ejs b/themes/landscape/layout/_partial/post/date.ejs new file mode 100644 index 0000000..3f49613 --- /dev/null +++ b/themes/landscape/layout/_partial/post/date.ejs @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/themes/landscape/layout/_partial/post/gallery.ejs b/themes/landscape/layout/_partial/post/gallery.ejs new file mode 100644 index 0000000..886c8ec --- /dev/null +++ b/themes/landscape/layout/_partial/post/gallery.ejs @@ -0,0 +1,11 @@ +<% if (post.photos && post.photos.length){ %> +
+
+ <% post.photos.forEach(function(photo, i){ %> + + + + <% }) %> +
+
+<% } %> \ No newline at end of file diff --git a/themes/landscape/layout/_partial/post/nav.ejs b/themes/landscape/layout/_partial/post/nav.ejs new file mode 100644 index 0000000..0406e5b --- /dev/null +++ b/themes/landscape/layout/_partial/post/nav.ejs @@ -0,0 +1,22 @@ +<% if (post.prev || post.next){ %> + +<% } %> \ No newline at end of file diff --git a/themes/landscape/layout/_partial/post/tag.ejs b/themes/landscape/layout/_partial/post/tag.ejs new file mode 100644 index 0000000..e0f327f --- /dev/null +++ b/themes/landscape/layout/_partial/post/tag.ejs @@ -0,0 +1,6 @@ +<% if (post.tags && post.tags.length){ %> + <%- list_tags(post.tags, { + show_count: false, + class: 'article-tag' + }) %> +<% } %> \ No newline at end of file diff --git a/themes/landscape/layout/_partial/post/title.ejs b/themes/landscape/layout/_partial/post/title.ejs new file mode 100644 index 0000000..69d646f --- /dev/null +++ b/themes/landscape/layout/_partial/post/title.ejs @@ -0,0 +1,15 @@ +<% if (post.link){ %> +

+ +

+<% } else if (post.title){ %> + <% if (index){ %> +

+ <%= post.title %> +

+ <% } else { %> +

+ <%= post.title %> +

+ <% } %> +<% } %> \ No newline at end of file diff --git a/themes/landscape/layout/_partial/sidebar.ejs b/themes/landscape/layout/_partial/sidebar.ejs new file mode 100644 index 0000000..c1e48e5 --- /dev/null +++ b/themes/landscape/layout/_partial/sidebar.ejs @@ -0,0 +1,5 @@ + \ No newline at end of file diff --git a/themes/landscape/layout/_widget/archive.ejs b/themes/landscape/layout/_widget/archive.ejs new file mode 100644 index 0000000..9a428ba --- /dev/null +++ b/themes/landscape/layout/_widget/archive.ejs @@ -0,0 +1,8 @@ +<% if (site.posts.length){ %> +
+

Archives

+
+ <%- list_archives() %> +
+
+<% } %> \ No newline at end of file diff --git a/themes/landscape/layout/_widget/category.ejs b/themes/landscape/layout/_widget/category.ejs new file mode 100644 index 0000000..7836a27 --- /dev/null +++ b/themes/landscape/layout/_widget/category.ejs @@ -0,0 +1,8 @@ +<% if (site.categories.length){ %> +
+

Categories

+
+ <%- list_categories() %> +
+
+<% } %> \ No newline at end of file diff --git a/themes/landscape/layout/_widget/recent_comments.ejs b/themes/landscape/layout/_widget/recent_comments.ejs new file mode 100644 index 0000000..4c60933 --- /dev/null +++ b/themes/landscape/layout/_widget/recent_comments.ejs @@ -0,0 +1,8 @@ +<% if (theme.duoshuo_shortname){ %> +
+

<%= __('最近评论') %>

+
+
    +
    +
    +<% } %> \ No newline at end of file diff --git a/themes/landscape/layout/_widget/recent_posts.ejs b/themes/landscape/layout/_widget/recent_posts.ejs new file mode 100644 index 0000000..7780920 --- /dev/null +++ b/themes/landscape/layout/_widget/recent_posts.ejs @@ -0,0 +1,14 @@ +<% if (site.posts.length){ %> +
    +

    Recents

    +
    + +
    +
    +<% } %> \ No newline at end of file diff --git a/themes/landscape/layout/_widget/tag.ejs b/themes/landscape/layout/_widget/tag.ejs new file mode 100644 index 0000000..c163c41 --- /dev/null +++ b/themes/landscape/layout/_widget/tag.ejs @@ -0,0 +1,8 @@ +<% if (site.tags.length){ %> +
    +

    Tags

    +
    + <%- list_tags() %> +
    +
    +<% } %> \ No newline at end of file diff --git a/themes/landscape/layout/_widget/tagcloud.ejs b/themes/landscape/layout/_widget/tagcloud.ejs new file mode 100644 index 0000000..4b82283 --- /dev/null +++ b/themes/landscape/layout/_widget/tagcloud.ejs @@ -0,0 +1,8 @@ +<% if (site.tags.length){ %> +
    +

    Tag Cloud

    +
    + <%- tagcloud() %> +
    +
    +<% } %> \ No newline at end of file diff --git a/themes/landscape/layout/archive.ejs b/themes/landscape/layout/archive.ejs new file mode 100644 index 0000000..52f9b21 --- /dev/null +++ b/themes/landscape/layout/archive.ejs @@ -0,0 +1 @@ +<%- partial('_partial/archive', {pagination: config.archive, index: true}) %> \ No newline at end of file diff --git a/themes/landscape/layout/category.ejs b/themes/landscape/layout/category.ejs new file mode 100644 index 0000000..3ffe252 --- /dev/null +++ b/themes/landscape/layout/category.ejs @@ -0,0 +1 @@ +<%- partial('_partial/archive', {pagination: config.category, index: true}) %> \ No newline at end of file diff --git a/themes/landscape/layout/index.ejs b/themes/landscape/layout/index.ejs new file mode 100644 index 0000000..60a2c68 --- /dev/null +++ b/themes/landscape/layout/index.ejs @@ -0,0 +1 @@ +<%- partial('_partial/archive', {pagination: 2, index: true}) %> \ No newline at end of file diff --git a/themes/landscape/layout/layout.ejs b/themes/landscape/layout/layout.ejs new file mode 100644 index 0000000..cf88daf --- /dev/null +++ b/themes/landscape/layout/layout.ejs @@ -0,0 +1,18 @@ +<%- partial('_partial/head') %> + +
    +
    + <%- partial('_partial/header', null, {cache: !config.relative_link}) %> +
    +
    <%- body %>
    + <% if (theme.sidebar && theme.sidebar !== 'bottom'){ %> + <%- partial('_partial/sidebar', null, {cache: !config.relative_link}) %> + <% } %> +
    + <%- partial('_partial/footer', null, {cache: !config.relative_link}) %> +
    + <%- partial('_partial/mobile-nav', null, {cache: !config.relative_link}) %> + <%- partial('_partial/after-footer') %> +
    + + \ No newline at end of file diff --git a/themes/landscape/layout/page.ejs b/themes/landscape/layout/page.ejs new file mode 100644 index 0000000..bea6318 --- /dev/null +++ b/themes/landscape/layout/page.ejs @@ -0,0 +1 @@ +<%- partial('_partial/article', {post: page, index: false}) %> \ No newline at end of file diff --git a/themes/landscape/layout/post.ejs b/themes/landscape/layout/post.ejs new file mode 100644 index 0000000..bea6318 --- /dev/null +++ b/themes/landscape/layout/post.ejs @@ -0,0 +1 @@ +<%- partial('_partial/article', {post: page, index: false}) %> \ No newline at end of file diff --git a/themes/landscape/layout/tag.ejs b/themes/landscape/layout/tag.ejs new file mode 100644 index 0000000..048cdb0 --- /dev/null +++ b/themes/landscape/layout/tag.ejs @@ -0,0 +1 @@ +<%- partial('_partial/archive', {pagination: config.tag, index: true}) %> \ No newline at end of file diff --git a/themes/landscape/package.json b/themes/landscape/package.json new file mode 100644 index 0000000..a11e9f6 --- /dev/null +++ b/themes/landscape/package.json @@ -0,0 +1,12 @@ +{ + "name": "hexo-theme-landscape", + "version": "0.0.1", + "private": true, + "devDependencies": { + "grunt": "~0.4.2", + "load-grunt-tasks": "~0.2.0", + "grunt-git": "~0.2.2", + "grunt-contrib-clean": "~0.5.0", + "grunt-contrib-copy": "~0.4.1" + } +} diff --git a/themes/landscape/scripts/fancybox.js b/themes/landscape/scripts/fancybox.js new file mode 100644 index 0000000..83f1fdc --- /dev/null +++ b/themes/landscape/scripts/fancybox.js @@ -0,0 +1,24 @@ +var rUrl = /((([A-Za-z]{3,9}:(?:\/\/)?)(?:[-;:&=\+\$,\w]+@)?[A-Za-z0-9.-]+|(?:www.|[-;:&=\+\$,\w]+@)[A-Za-z0-9.-]+)((?:\/[\+~%\/.\w-_]*)?\??(?:[-\+=&;%@.\w_]*)#?(?:[.\!\/\\w]*))?)/; + +/** +* Fancybox tag +* +* Syntax: +* {% fancybox /path/to/image [/path/to/thumbnail] [title] %} +*/ + +hexo.extend.tag.register('fancybox', function(args){ + var original = args.shift(), + thumbnail = ''; + + if (args.length && rUrl.test(args[0])){ + thumbnail = args.shift(); + } + + var title = args.join(' '); + + return '' + + '' + title + '' + '' + + (title ? '' + title + '' : ''); +}); \ No newline at end of file diff --git a/themes/landscape/source/css/_extend.styl b/themes/landscape/source/css/_extend.styl new file mode 100644 index 0000000..96a1817 --- /dev/null +++ b/themes/landscape/source/css/_extend.styl @@ -0,0 +1,63 @@ +$block-caption + text-decoration: none + text-transform: uppercase + letter-spacing: 2px + color: color-grey + margin-bottom: 1em + margin-left: 5px + line-height: 1em + text-shadow: 0 1px #fff + font-weight: bold + +$block + background: #fff + box-shadow: 1px 2px 3px #ddd + border: 1px solid color-border + border-radius: 3px + +$base-style + h1 + font-size: 2em + h2 + font-size: 1.5em + h3 + font-size: 1.3em + h4 + font-size: 1.2em + h5 + font-size: 1em + h6 + font-size: 1em + color: color-grey + hr + border: 1px dashed color-border + strong + font-weight: bold + em, cite + font-style: italic + sup, sub + font-size: 0.75em + line-height: 0 + position: relative + vertical-align: baseline + sup + top: -0.5em + sub + bottom: -0.2em + small + font-size: 0.85em + acronym, abbr + border-bottom: 1px dotted + ul, ol, dl + margin: 0 20px + line-height: line-height + ul, ol + ul, ol + margin-top: 0 + margin-bottom: 0 + ul + list-style: disc + ol + list-style: decimal + dt + font-weight: bold \ No newline at end of file diff --git a/themes/landscape/source/css/_partial/archive.styl b/themes/landscape/source/css/_partial/archive.styl new file mode 100644 index 0000000..90ef053 --- /dev/null +++ b/themes/landscape/source/css/_partial/archive.styl @@ -0,0 +1,80 @@ +.archives-wrap + margin: block-margin 0 + +.archives + clearfix() + +.archive-year-wrap + margin-bottom: 1em + +.archive-year + @extend $block-caption + +.archives + column-gap: 10px + @media mq-tablet + column-count: 2 + @media mq-normal + column-count: 3 + +.archive-article + avoid-column-break() + +.archive-article-inner + @extend $block + padding: 10px + margin-bottom: 15px + +.archive-article-title + text-decoration: none + font-weight: bold + color: color-default + transition: color 0.2s + line-height: line-height + &:hover + color: color-link + +.archive-article-footer + margin-top: 1em + +.archive-article-date + color: color-grey + text-decoration: none + font-size: 0.85em + line-height: 1em + margin-bottom: 0.5em + display: block + +#page-nav + clearfix() + margin: block-margin auto + background: #fff + box-shadow: 1px 2px 3px #ddd + border: 1px solid color-border + border-radius: 3px + text-align: center + color: color-grey + overflow: hidden + a, span + padding: 10px 20px + line-height: 1 + height: 2ex + a + color: color-grey + text-decoration: none + &:hover + background: color-grey + color: #fff + .prev + float: left + .next + float: right + .page-number + display: inline-block + @media mq-mobile + display: none + .current + color: color-default + font-weight: bold + .space + color: color-border \ No newline at end of file diff --git a/themes/landscape/source/css/_partial/article.styl b/themes/landscape/source/css/_partial/article.styl new file mode 100644 index 0000000..46094f9 --- /dev/null +++ b/themes/landscape/source/css/_partial/article.styl @@ -0,0 +1,357 @@ +.article + margin: block-margin 0 + +.article-inner + @extend $block + overflow: hidden + +.article-meta + clearfix() + +.article-date + @extend $block-caption + float: left + +.article-category + float: left + line-height: 1em + color: #ccc + text-shadow: 0 1px #fff + margin-left: 8px + &:before + content: "\2022" + +.article-category-link + @extend $block-caption + margin: 0 12px 1em + +.article-header + padding: article-padding article-padding 0 + +.article-title + text-decoration: none + font-size: 2em + font-weight: bold + color: color-default + line-height: line-height-title + transition: color 0.2s + a&:hover + color: color-link + +.article-entry + @extend $base-style + clearfix() + color: color-default + padding: 0 article-padding + p, table + line-height: line-height + margin: line-height 0 + h1, h2, h3, h4, h5, h6 + font-weight: bold + h1, h2, h3, h4, h5, h6 + line-height: line-height-title + margin: line-height-title 0 + a + color: color-link + text-decoration: none + &:hover + text-decoration: underline + ul, ol, dl + margin-top: line-height + margin-bottom: line-height + img, video + max-width: 100% + height: auto + display: block + margin: auto + iframe + border: none + table + width: 100% + border-collapse: collapse + border-spacing: 0 + th + font-weight: bold + border-bottom: 3px solid color-border + padding-bottom: 0.5em + td + border-bottom: 1px solid color-border + padding: 10px 0 + blockquote + font-family: font-serif + font-size: 1.4em + margin: line-height 20px + text-align: center + footer + font-size: font-size + margin: line-height 0 + font-family: font-sans + cite + &:before + content: "—" + padding: 0 0.5em + .pullquote + text-align: left + width: 45% + margin: 0 + &.left + margin-left: 0.5em + margin-right: 1em + &.right + margin-right: 0.5em + margin-left: 1em + .caption + color: color-grey + display: block + font-size: 0.9em + margin-top: 0.5em + position: relative + text-align: center + // http://webdesignerwall.com/tutorials/css-elastic-videos + .video-container + position: relative + padding-top: (9 / 16 * 100)% // 16:9 ratio + height: 0 + overflow: hidden + iframe, object, embed + position: absolute + top: 0 + left: 0 + width: 100% + height: 100% + margin-top: 0 + +.article-more-link a + display: inline-block + line-height: 1em + padding: 6px 15px + border-radius: 15px + background: color-background + color: color-grey + text-shadow: 0 1px #fff + text-decoration: none + &:hover + background: color-link + color: #fff + text-decoration: none + text-shadow: 0 1px darken(color-link, 20%) + +.article-footer + clearfix() + font-size: 0.85em + line-height: line-height + border-top: 1px solid color-border + padding-top: line-height + margin: 0 article-padding article-padding + a + color: color-grey + text-decoration: none + &:hover + color: color-default + +.article-tag-list-item + float: left + margin-right: 10px + +.article-tag-list-link + &:before + content: "#" + +.article-comment-link + float: right + &:before + content: "\f075" + font-family: font-icon + padding-right: 8px + +.article-share-link + cursor: pointer + float: right + margin-left: 20px + &:before + content: "\f064" + font-family: font-icon + padding-right: 6px + +#article-nav + clearfix() + position: relative + @media mq-normal + margin: block-margin 0 + &:before + absolute-center(8px) + content: "" + border-radius: 50% + background: color-border + box-shadow: 0 1px 2px #fff + +.article-nav-link-wrap + text-decoration: none + text-shadow: 0 1px #fff + color: color-grey + box-sizing: border-box + margin-top: block-margin + text-align: center + display: block + &:hover + color: color-default + @media mq-normal + width: 50% + margin-top: 0 + +#article-nav-newer + @media mq-normal + float: left + text-align: right + padding-right: 20px + +#article-nav-older + @media mq-normal + float: right + text-align: left + padding-left: 20px + +.article-nav-caption + text-transform: uppercase + letter-spacing: 2px + color: color-border + line-height: 1em + font-weight: bold + #article-nav-newer & + margin-right: -2px + +.article-nav-title + font-size: 0.85em + line-height: line-height + margin-top: 0.5em + +.article-share-box + position: absolute + display: none + background: #fff + box-shadow: 1px 2px 10px rgba(0, 0, 0, 0.2) + border-radius: 3px + margin-left: -145px + overflow: hidden + z-index: 1 + &.on + display: block + +.article-share-input + width: 100% + background: none + box-sizing: border-box + font: 14px font-sans + padding: 0 15px + color: color-default + outline: none + border: 1px solid color-border + border-radius: 3px 3px 0 0 + height: 36px + line-height: 36px + +.article-share-links + clearfix() + background: color-background + +$article-share-link + width: 50px + height: 36px + display: block + float: left + position: relative + color: #999 + text-shadow: 0 1px #fff + &:before + font-size: 20px + font-family: font-icon + absolute-center(@font-size) + text-align: center + &:hover + color: #fff + +.article-share-twitter + @extend $article-share-link + &:before + content: "\f099" + &:hover + background: color-twitter + text-shadow: 0 1px darken(color-twitter, 20%) + +.article-share-facebook + @extend $article-share-link + &:before + content: "\f09a" + &:hover + background: color-facebook + text-shadow: 0 1px darken(color-facebook, 20%) + +.article-share-pinterest + @extend $article-share-link + &:before + content: "\f0d2" + &:hover + background: color-pinterest + text-shadow: 0 1px darken(color-pinterest, 20%) + +.article-share-google + @extend $article-share-link + &:before + content: "\f0d5" + &:hover + background: color-google + text-shadow: 0 1px darken(color-google, 20%) + +.article-gallery + background: #000 + position: relative + +.article-gallery-photos + position: relative + overflow: hidden + +.article-gallery-img + display: none + max-width: 100% + &:first-child + display: block + &.loaded + position: absolute + display: block + img + display: block + max-width: 100% + margin: 0 auto +/* +$article-gallery-ctrl + position: absolute + top: 0 + height: 100% + width: 60px + color: #fff + text-shadow: 0 0 3px rgba(0, 0, 0, 0.3) + opacity: 0.3 + transition: opacity 0.2s + cursor: pointer + &:hover + opacity: 0.8 + &:before + font-size: 30px + font-family: font-icon + position: absolute + top: 50% + margin-top: @font-size * -0.5 + +.article-gallery-prev + @extend $article-gallery-ctrl + left: 0 + &:before + content: "\f053" + left: 15px + +.article-gallery-next + @extend $article-gallery-ctrl + right: 0 + &:before + content: "\f054" + right: 15px*/ \ No newline at end of file diff --git a/themes/landscape/source/css/_partial/comment.styl b/themes/landscape/source/css/_partial/comment.styl new file mode 100644 index 0000000..296b7dd --- /dev/null +++ b/themes/landscape/source/css/_partial/comment.styl @@ -0,0 +1,9 @@ +#comments + background: #fff + box-shadow: 1px 2px 3px #ddd + padding: article-padding + border: 1px solid color-border + border-radius: 3px + margin: block-margin 0 + a + color: color-link \ No newline at end of file diff --git a/themes/landscape/source/css/_partial/footer.styl b/themes/landscape/source/css/_partial/footer.styl new file mode 100644 index 0000000..fe2fd24 --- /dev/null +++ b/themes/landscape/source/css/_partial/footer.styl @@ -0,0 +1,14 @@ +#footer + background: color-footer-background + padding: 50px 0 + border-top: 1px solid color-border + color: color-grey + a + color: color-link + text-decoration: none + &:hover + text-decoration: underline + +#footer-info + line-height: line-height + font-size: 0.85em \ No newline at end of file diff --git a/themes/landscape/source/css/_partial/header.styl b/themes/landscape/source/css/_partial/header.styl new file mode 100644 index 0000000..d18ebc8 --- /dev/null +++ b/themes/landscape/source/css/_partial/header.styl @@ -0,0 +1,165 @@ +#header + height: banner-height + position: relative + border-bottom: 1px solid color-border + &:before, &:after + content: "" + position: absolute + left: 0 + right: 0 + height: 40px + &:before + top: 0 + background: linear-gradient(rgba(0, 0, 0, 0.2), transparent) + &:after + bottom: 0 + background: linear-gradient(transparent, rgba(0, 0, 0, 0.2)) + +#header-outer + height: 100% + position: relative + +#header-inner + position: relative + overflow: hidden + +#banner + position: absolute + top: 0 + left: 0 + width: 100% + height: 100% + background: url(banner-url) center #000 + background-size: cover + z-index: -1 + +#header-title + text-align: center + height: logo-size + position: absolute + top: 50% + left: 0 + margin-top: logo-size * -0.5 + +$logo-text + text-decoration: none + color: #fff + font-weight: 300 + text-shadow: 0 1px 4px rgba(0, 0, 0, 0.3) + +#logo + @extend $logo-text + font-size: logo-size + line-height: logo-size + letter-spacing: 2px + +#subtitle + @extend $logo-text + font-size: subtitle-size + line-height: subtitle-size + letter-spacing: 1px + +#subtitle-wrap + margin-top: subtitle-size + +#main-nav + float: left + margin-left: -15px + +$nav-link + float: left + color: #fff + opacity: 0.6 + text-decoration: none + text-shadow: 0 1px rgba(0, 0, 0, 0.2) + transition: opacity 0.2s + display: block + padding: 20px 15px + &:hover + opacity: 1 + +.nav-icon + @extend $nav-link + font-family: font-icon + text-align: center + font-size: font-size + width: font-size + height: font-size + padding: 20px 15px + position: relative + cursor: pointer + +.main-nav-link + @extend $nav-link + font-weight: 300 + letter-spacing: 1px + @media mq-mobile + display: none + +#main-nav-toggle + display: none + &:before + content: "\f0c9" + @media mq-mobile + display: block + +#sub-nav + float: right + margin-right: -15px + +#nav-rss-link + &:before + content: "\f09e" + +#nav-search-btn + &:before + content: "\f002" + +#search-form-wrap + position: absolute + top: 15px + width: 150px + height: 30px + right: -150px + opacity: 0 + transition: 0.2s ease-out + &.on + opacity: 1 + right: 0 + @media mq-mobile + width: 100% + right: -100% + +.search-form + position: absolute + top: 0 + left: 0 + right: 0 + background: #fff + padding: 5px 15px + border-radius: 15px + box-shadow: 0 0 10px rgba(0, 0, 0, 0.3) + +.search-form-input + border: none + background: none + color: color-default + width: 100% + font: 13px font-sans + outline: none + &::-webkit-search-results-decoration + &::-webkit-search-cancel-button + -webkit-appearance: none + +.search-form-submit + position: absolute + top: 50% + right: 10px + margin-top: -7px + font: 13px font-icon + border: none + background: none + color: #bbb + cursor: pointer + &:hover, &:focus + color: #777 \ No newline at end of file diff --git a/themes/landscape/source/css/_partial/highlight.styl b/themes/landscape/source/css/_partial/highlight.styl new file mode 100644 index 0000000..ccc352c --- /dev/null +++ b/themes/landscape/source/css/_partial/highlight.styl @@ -0,0 +1,156 @@ +// https://github.com/chriskempson/tomorrow-theme +highlight-background = #2d2d2d +highlight-current-line = #393939 +highlight-selection = #515151 +highlight-foreground = #cccccc +highlight-comment = #999999 +highlight-red = #f2777a +highlight-orange = #f99157 +highlight-yellow = #ffcc66 +highlight-green = #99cc99 +highlight-aqua = #66cccc +highlight-blue = #6699cc +highlight-purple = #cc99cc + +$code-block + background: highlight-background + margin: 0 article-padding * -1 + padding: 15px article-padding + border-style: solid + border-color: color-border + border-width: 1px 0 + overflow: auto + color: highlight-foreground + line-height: font-size * line-height + +$line-numbers + color: #666 + font-size: 0.85em + +.article-entry + pre, code + font-family: font-mono + code + background: color-background + text-shadow: 0 1px #fff + padding: 0 0.3em + pre + @extend $code-block + code + background: none + text-shadow: none + padding: 0 + .highlight + @extend $code-block + pre + border: none + margin: 0 + padding: 0 + table + margin: 0 + width: auto + td + border: none + padding: 0 + figcaption + clearfix() + font-size: 0.85em + color: highlight-comment + line-height: 1em + margin-bottom: 1em + a + float: right + .gutter pre + @extend $line-numbers + text-align: right + padding-right: 20px + .line + height: font-size * line-height + .gist + margin: 0 article-padding * -1 + border-style: solid + border-color: color-border + border-width: 1px 0 + background: highlight-background + padding: 15px article-padding 15px 0 + .gist-file + border: none + font-family: font-mono + margin: 0 + .gist-data + background: none + border: none + .line-numbers + @extend $line-numbers + background: none + border: none + padding: 0 20px 0 0 + .line-data + padding: 0 !important + .highlight + margin: 0 + padding: 0 + border: none + .gist-meta + background: highlight-background + color: highlight-comment + font: 0.85em font-sans + text-shadow: 0 0 + padding: 0 + margin-top: 1em + margin-left: article-padding + a + color: color-link + font-weight: normal + &:hover + text-decoration: underline + +pre + .comment + .title + color: highlight-comment + .variable + .attribute + .tag + .regexp + .ruby .constant + .xml .tag .title + .xml .pi + .xml .doctype + .html .doctype + .css .id + .css .class + .css .pseudo + color: highlight-red + .number + .preprocessor + .built_in + .literal + .params + .constant + color: highlight-orange + .class + .ruby .class .title + .css .rules .attribute + color: highlight-green + .string + .value + .inheritance + .header + .ruby .symbol + .xml .cdata + color: highlight-green + .css .hexcolor + color: highlight-aqua + .function + .python .decorator + .python .title + .ruby .function .title + .ruby .title .keyword + .perl .sub + .javascript .title + .coffeescript .title + color: highlight-blue + .keyword + .javascript .function + color: highlight-purple \ No newline at end of file diff --git a/themes/landscape/source/css/_partial/mobile.styl b/themes/landscape/source/css/_partial/mobile.styl new file mode 100644 index 0000000..eb68b3a --- /dev/null +++ b/themes/landscape/source/css/_partial/mobile.styl @@ -0,0 +1,19 @@ +@media mq-mobile + #mobile-nav + position: absolute + top: 0 + left: 0 + width: mobile-nav-width + height: 100% + background: color-mobile-nav-background + border-right: 1px solid #fff + +@media mq-mobile + .mobile-nav-link + display: block + color: color-grey + text-decoration: none + padding: 15px 20px + font-weight: bold + &:hover + color: #fff diff --git a/themes/landscape/source/css/_partial/sidebar-aside.styl b/themes/landscape/source/css/_partial/sidebar-aside.styl new file mode 100644 index 0000000..838b167 --- /dev/null +++ b/themes/landscape/source/css/_partial/sidebar-aside.styl @@ -0,0 +1,27 @@ +#sidebar + @media mq-normal + column(sidebar-column) + +.widget-wrap + margin: block-margin 0 + +.widget-title + @extend $block-caption + +.widget + color: color-sidebar-text + text-shadow: 0 1px #fff + background: color-widget-background + box-shadow: 0 -1px 4px color-widget-border inset + border: 1px solid color-widget-border + padding: 15px + border-radius: 3px + a + color: color-link + text-decoration: none + &:hover + text-decoration: underline + ul, ol, dl + ul, ol, dl + margin-left: 15px + list-style: disc \ No newline at end of file diff --git a/themes/landscape/source/css/_partial/sidebar-bottom.styl b/themes/landscape/source/css/_partial/sidebar-bottom.styl new file mode 100644 index 0000000..b385275 --- /dev/null +++ b/themes/landscape/source/css/_partial/sidebar-bottom.styl @@ -0,0 +1,15 @@ +.widget-wrap + margin-bottom: block-margin !important + @media mq-normal + column(sidebar-column) + +.widget-title + color: #ccc + text-transform: uppercase + letter-spacing: 2px + margin-bottom: 1em + line-height: 1em + font-weight: bold + +.widget + color: color-grey \ No newline at end of file diff --git a/themes/landscape/source/css/_partial/sidebar.styl b/themes/landscape/source/css/_partial/sidebar.styl new file mode 100644 index 0000000..e43d66a --- /dev/null +++ b/themes/landscape/source/css/_partial/sidebar.styl @@ -0,0 +1,35 @@ +if sidebar is bottom + @import "sidebar-bottom" +else + @import "sidebar-aside" + +.widget + @extend $base-style + line-height: line-height + word-wrap: break-word + font-size: 0.9em + ul, ol + list-style: none + margin: 0 + ul, ol + margin: 0 20px + ul + list-style: disc + ol + list-style: decimal + +.category-list-count +.tag-list-count +.archive-list-count + padding-left: 5px + color: color-grey + font-size: 0.85em + &:before + content: "(" + &:after + content: ")" + +.tagcloud + a + margin-right: 5px + display: inline-block diff --git a/themes/landscape/source/css/_util/grid.styl b/themes/landscape/source/css/_util/grid.styl new file mode 100644 index 0000000..2a14dd2 --- /dev/null +++ b/themes/landscape/source/css/_util/grid.styl @@ -0,0 +1,38 @@ +///////////////// +// Semantic.gs // for Stylus: http://learnboost.github.com/stylus/ +///////////////// + +// Utility function — you should never need to modify this +// _gridsystem-width = (column-width + gutter-width) * columns +gridsystem-width(_columns = columns) + (column-width + gutter-width) * _columns + +// Set @total-width to 100% for a fluid layout +// total-width = gridsystem-width(columns) +total-width = 100% + +////////// +// GRID // +////////// + +body + clearfix() + width: 100% + +row(_columns = columns) + clearfix() + display: block + width: total-width * ((gutter-width + gridsystem-width(_columns)) / gridsystem-width(_columns)) + margin: 0 total-width * (((gutter-width * .5) / gridsystem-width(_columns)) * -1) + +column(x, _columns = columns) + display: inline + float: left + width: total-width * ((((gutter-width + column-width) * x) - gutter-width) / gridsystem-width(_columns)) + margin: 0 total-width * ((gutter-width * .5) / gridsystem-width(_columns)) + +push(offset = 1) + margin-left: total-width * (((gutter-width + column-width) * offset) / gridsystem-width(columns)) + +pull(offset = 1) + margin-right: total-width * (((gutter-width + column-width) * offset) / gridsystem-width(columns)) \ No newline at end of file diff --git a/themes/landscape/source/css/_util/mixin.styl b/themes/landscape/source/css/_util/mixin.styl new file mode 100644 index 0000000..b56f037 --- /dev/null +++ b/themes/landscape/source/css/_util/mixin.styl @@ -0,0 +1,31 @@ +// http://www.zeldman.com/2012/03/01/replacing-the-9999px-hack-new-image-replacement/ +hide-text() + text-indent: 100% + white-space: nowrap + overflow: hidden + +// http://codepen.io/shshaw/full/gEiDt +absolute-center(width, height = width) + // margin: auto + // position: absolute + // top: 50% + // top: 0 + // left: 0 + // bottom: 0 + // right: 0 + // width: width + // height: height + // overflow: auto + width: width + height: height + position: absolute + top: 50% + left: 50% + margin-top: width * -0.5 + margin-left: height * -0.5 + +avoid-column-break() + vendor("column-break-inside", avoid, only: webkit) + page-break-inside: avoid // for firefox + overflow: hidden // fix for firefox + break-inside: avoid-column diff --git a/themes/landscape/source/css/_variables.styl b/themes/landscape/source/css/_variables.styl new file mode 100644 index 0000000..1215bb1 --- /dev/null +++ b/themes/landscape/source/css/_variables.styl @@ -0,0 +1,60 @@ +// Config +support-for-ie = false +vendor-prefixes = webkit moz ms official + +// Colors +color-default = #555 +color-grey = #999 +color-border = #ddd +color-link = #258fb8 +color-background = #eee +color-sidebar-text = #777 +color-widget-background = #ddd +color-widget-border = #ccc +color-footer-background = #262a30 +color-mobile-nav-background = #191919 +color-twitter = #00aced +color-facebook = #3b5998 +color-pinterest = #cb2027 +color-google = #dd4b39 + +// Fonts +font-sans = "Helvetica Neue", Helvetica, Arial, sans-serif +font-serif = Georgia, "Times New Roman", serif +font-mono = "Source Code Pro", Consolas, Monaco, Menlo, Consolas, monospace +font-icon = FontAwesome +font-icon-path = "fonts/fontawesome-webfont" +font-icon-version = "4.0.3" +font-size = 14px +line-height = 1.6em +line-height-title = 1.1em + +// Header +logo-size = 40px +subtitle-size = 16px +banner-height = 300px +banner-url = "images/banner.jpg" + +sidebar = hexo-config("sidebar") + +// Layout +block-margin = 50px +article-padding = 20px +mobile-nav-width = 280px +main-column = 9 +sidebar-column = 3 + +if sidebar and sidebar isnt bottom + _sidebar-column = sidebar-column +else + _sidebar-column = 0 + +// Grids +column-width = 80px +gutter-width = 20px +columns = main-column + _sidebar-column + +// Media queries +mq-mobile = "screen and (max-width: 479px)" +mq-tablet = "screen and (min-width: 480px) and (max-width: 767px)" +mq-normal = "screen and (min-width: 768px)" \ No newline at end of file diff --git a/css/fonts/FontAwesome.otf b/themes/landscape/source/css/fonts/FontAwesome.otf similarity index 100% rename from css/fonts/FontAwesome.otf rename to themes/landscape/source/css/fonts/FontAwesome.otf diff --git a/css/fonts/fontawesome-webfont.eot b/themes/landscape/source/css/fonts/fontawesome-webfont.eot similarity index 100% rename from css/fonts/fontawesome-webfont.eot rename to themes/landscape/source/css/fonts/fontawesome-webfont.eot diff --git a/css/fonts/fontawesome-webfont.svg b/themes/landscape/source/css/fonts/fontawesome-webfont.svg similarity index 100% rename from css/fonts/fontawesome-webfont.svg rename to themes/landscape/source/css/fonts/fontawesome-webfont.svg diff --git a/css/fonts/fontawesome-webfont.ttf b/themes/landscape/source/css/fonts/fontawesome-webfont.ttf similarity index 100% rename from css/fonts/fontawesome-webfont.ttf rename to themes/landscape/source/css/fonts/fontawesome-webfont.ttf diff --git a/css/fonts/fontawesome-webfont.woff b/themes/landscape/source/css/fonts/fontawesome-webfont.woff similarity index 100% rename from css/fonts/fontawesome-webfont.woff rename to themes/landscape/source/css/fonts/fontawesome-webfont.woff diff --git a/css/images/banner.jpg b/themes/landscape/source/css/images/banner.jpg similarity index 100% rename from css/images/banner.jpg rename to themes/landscape/source/css/images/banner.jpg diff --git a/themes/landscape/source/css/style.styl b/themes/landscape/source/css/style.styl new file mode 100644 index 0000000..c51f8e4 --- /dev/null +++ b/themes/landscape/source/css/style.styl @@ -0,0 +1,89 @@ +@import "nib" +@import "_variables" +@import "_util/mixin" +@import "_util/grid" + +global-reset() + +input, button + margin: 0 + padding: 0 + &::-moz-focus-inner + border: 0 + padding: 0 + +@font-face + font-family: FontAwesome + font-style: normal + font-weight: normal + src: url(font-icon-path + ".eot?v=#" + font-icon-version) + src: url(font-icon-path + ".eot?#iefix&v=#" + font-icon-version) format("embedded-opentype"), + url(font-icon-path + ".woff?v=#" + font-icon-version) format("woff"), + url(font-icon-path + ".ttf?v=#" + font-icon-version) format("truetype"), + url(font-icon-path + ".svg#fontawesomeregular?v=#" + font-icon-version) format("svg") + +html, body, #container + height: 100% + +body + background: color-background + font: font-size font-sans + -webkit-text-size-adjust: 100% + +.outer + clearfix() + max-width: (column-width + gutter-width) * columns + gutter-width + margin: 0 auto + padding: 0 gutter-width + +.inner + column(columns) + +.left, .alignleft + float: left + +.right, .alignright + float: right + +.clear + clear: both + +#container + position: relative + +.mobile-nav-on + overflow: hidden + +#wrap + height: 100% + width: 100% + position: absolute + top: 0 + left: 0 + transition: 0.2s ease-out + z-index: 1 + background: color-background + .mobile-nav-on & + left: mobile-nav-width + +if sidebar and sidebar isnt bottom + #main + @media mq-normal + column(main-column) + +if sidebar is left + @media mq-normal + #main + float: right + +@import "_extend" +@import "_partial/header" +@import "_partial/article" +@import "_partial/comment" +@import "_partial/archive" +@import "_partial/footer" +@import "_partial/highlight" +@import "_partial/mobile" + +if sidebar + @import "_partial/sidebar" \ No newline at end of file diff --git a/fancybox/blank.gif b/themes/landscape/source/fancybox/blank.gif similarity index 100% rename from fancybox/blank.gif rename to themes/landscape/source/fancybox/blank.gif diff --git a/fancybox/fancybox_loading.gif b/themes/landscape/source/fancybox/fancybox_loading.gif similarity index 100% rename from fancybox/fancybox_loading.gif rename to themes/landscape/source/fancybox/fancybox_loading.gif diff --git a/fancybox/fancybox_loading@2x.gif b/themes/landscape/source/fancybox/fancybox_loading@2x.gif similarity index 100% rename from fancybox/fancybox_loading@2x.gif rename to themes/landscape/source/fancybox/fancybox_loading@2x.gif diff --git a/fancybox/fancybox_overlay.png b/themes/landscape/source/fancybox/fancybox_overlay.png similarity index 100% rename from fancybox/fancybox_overlay.png rename to themes/landscape/source/fancybox/fancybox_overlay.png diff --git a/fancybox/fancybox_sprite.png b/themes/landscape/source/fancybox/fancybox_sprite.png similarity index 100% rename from fancybox/fancybox_sprite.png rename to themes/landscape/source/fancybox/fancybox_sprite.png diff --git a/fancybox/fancybox_sprite@2x.png b/themes/landscape/source/fancybox/fancybox_sprite@2x.png similarity index 100% rename from fancybox/fancybox_sprite@2x.png rename to themes/landscape/source/fancybox/fancybox_sprite@2x.png diff --git a/fancybox/helpers/fancybox_buttons.png b/themes/landscape/source/fancybox/helpers/fancybox_buttons.png similarity index 100% rename from fancybox/helpers/fancybox_buttons.png rename to themes/landscape/source/fancybox/helpers/fancybox_buttons.png diff --git a/fancybox/helpers/jquery.fancybox-buttons.css b/themes/landscape/source/fancybox/helpers/jquery.fancybox-buttons.css similarity index 100% rename from fancybox/helpers/jquery.fancybox-buttons.css rename to themes/landscape/source/fancybox/helpers/jquery.fancybox-buttons.css diff --git a/fancybox/helpers/jquery.fancybox-buttons.js b/themes/landscape/source/fancybox/helpers/jquery.fancybox-buttons.js similarity index 100% rename from fancybox/helpers/jquery.fancybox-buttons.js rename to themes/landscape/source/fancybox/helpers/jquery.fancybox-buttons.js diff --git a/fancybox/helpers/jquery.fancybox-media.js b/themes/landscape/source/fancybox/helpers/jquery.fancybox-media.js similarity index 100% rename from fancybox/helpers/jquery.fancybox-media.js rename to themes/landscape/source/fancybox/helpers/jquery.fancybox-media.js diff --git a/fancybox/helpers/jquery.fancybox-thumbs.css b/themes/landscape/source/fancybox/helpers/jquery.fancybox-thumbs.css similarity index 100% rename from fancybox/helpers/jquery.fancybox-thumbs.css rename to themes/landscape/source/fancybox/helpers/jquery.fancybox-thumbs.css diff --git a/fancybox/helpers/jquery.fancybox-thumbs.js b/themes/landscape/source/fancybox/helpers/jquery.fancybox-thumbs.js similarity index 100% rename from fancybox/helpers/jquery.fancybox-thumbs.js rename to themes/landscape/source/fancybox/helpers/jquery.fancybox-thumbs.js diff --git a/fancybox/jquery.fancybox.css b/themes/landscape/source/fancybox/jquery.fancybox.css similarity index 100% rename from fancybox/jquery.fancybox.css rename to themes/landscape/source/fancybox/jquery.fancybox.css diff --git a/fancybox/jquery.fancybox.js b/themes/landscape/source/fancybox/jquery.fancybox.js similarity index 100% rename from fancybox/jquery.fancybox.js rename to themes/landscape/source/fancybox/jquery.fancybox.js diff --git a/fancybox/jquery.fancybox.pack.js b/themes/landscape/source/fancybox/jquery.fancybox.pack.js similarity index 100% rename from fancybox/jquery.fancybox.pack.js rename to themes/landscape/source/fancybox/jquery.fancybox.pack.js diff --git a/js/script.js b/themes/landscape/source/js/script.js similarity index 100% rename from js/script.js rename to themes/landscape/source/js/script.js