Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

NUIPreprocessor added #356

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions Demo/NUIDemo.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@
0EE9CA7D191ECA0F00C84934 /* TestTheme.NUI.nss in Resources */ = {isa = PBXBuildFile; fileRef = 0EE9CA7B191EC96D00C84934 /* TestTheme.NUI.nss */; };
165D32561BF2239900BF3069 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 165D32551BF2239900BF3069 /* Images.xcassets */; };
3830C7C440594F829971E4C2 /* libPods-NUITests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 7CC7736AC8944034A5E10550 /* libPods-NUITests.a */; };
3AD433F41D2BD7B5008C4ED5 /* NUIPreprocessor.m in Sources */ = {isa = PBXBuildFile; fileRef = 3AD433F31D2BD7B5008C4ED5 /* NUIPreprocessor.m */; };
41A0DE98FD464C508748F886 /* libPods-NUIDemo.a in Frameworks */ = {isa = PBXBuildFile; fileRef = B8B8BB2BB5E6412588AE14FA /* libPods-NUIDemo.a */; };
4A0B8636165EE59A005B5756 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4A0B8635165EE59A005B5756 /* UIKit.framework */; };
4A0B8638165EE59A005B5756 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4A0B8637165EE59A005B5756 /* Foundation.framework */; };
Expand Down Expand Up @@ -198,6 +199,8 @@
0EE9CA7B191EC96D00C84934 /* TestTheme.NUI.nss */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = TestTheme.NUI.nss; sourceTree = "<group>"; };
165D32551BF2239900BF3069 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = "<group>"; };
1B8E11A50FE5F75C66ACDBBD /* Pods-NUITests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-NUITests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-NUITests/Pods-NUITests.debug.xcconfig"; sourceTree = "<group>"; };
3AD433F21D2BD7B5008C4ED5 /* NUIPreprocessor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NUIPreprocessor.h; sourceTree = "<group>"; };
3AD433F31D2BD7B5008C4ED5 /* NUIPreprocessor.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NUIPreprocessor.m; sourceTree = "<group>"; };
3AE80CFA17E0EB290065FB3D /* NUIConstants.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NUIConstants.h; sourceTree = "<group>"; };
4A0B8631165EE59A005B5756 /* NUIDemo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = NUIDemo.app; sourceTree = BUILT_PRODUCTS_DIR; };
4A0B8635165EE59A005B5756 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; };
Expand Down Expand Up @@ -704,6 +707,8 @@
4A744B18169904500068F3CF /* NUIFileMonitor.m */,
89B940271671418100850A9A /* NUIGraphics.h */,
89B940281671418100850A9A /* NUIGraphics.m */,
3AD433F21D2BD7B5008C4ED5 /* NUIPreprocessor.h */,
3AD433F31D2BD7B5008C4ED5 /* NUIPreprocessor.m */,
89B940291671418100850A9A /* NUIRenderer.h */,
89B9402A1671418100850A9A /* NUIRenderer.m */,
89B9402B1671418100850A9A /* NUISettings.h */,
Expand Down Expand Up @@ -1185,6 +1190,7 @@
D983DEE8169DC05300A3A180 /* UIToolbar+NUI.m in Sources */,
D983DF1C169DC84600A3A180 /* UISlider+NUI.m in Sources */,
D983DF1F169DC87800A3A180 /* NUISliderRenderer.m in Sources */,
3AD433F41D2BD7B5008C4ED5 /* NUIPreprocessor.m in Sources */,
4ADA71C616A0F15C00BDCF81 /* UISearchBar+NUI.m in Sources */,
4ADA71CA16A103CD00BDCF81 /* NUISearchBarRenderer.m in Sources */,
D8E7168116B8AF4400686854 /* NUIControlRenderer.m in Sources */,
Expand Down
1 change: 0 additions & 1 deletion NUI/Core/NUIFileMonitor.m
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ +(void)watch:(NSString*)path withCallback:(void(^)())callback
if (flags) {
dispatch_source_cancel(source);
callback();
[self watch:path withCallback:callback];
}
});
dispatch_source_set_cancel_handler(source, ^(void)
Expand Down
16 changes: 16 additions & 0 deletions NUI/Core/NUIPreprocessor.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
//
// NUIPreprocessor.h
// NUIDemo
//
// Created by imihaly on 04/07/16.
// Copyright © 2016 Tom Benner. All rights reserved.
//

#import <Foundation/Foundation.h>

@interface NUIPreprocessor : NSObject

+ (NSString *)preprocessFileAtPath:(NSString *)path;
+ (NSArray *)dependenciesOfFileAtPath:(NSString *)path;

@end
110 changes: 110 additions & 0 deletions NUI/Core/NUIPreprocessor.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
//
// NUIPreprocessor.m
// NUIDemo
//
// Created by imihaly on 04/07/16.
// Copyright © 2016 Tom Benner. All rights reserved.
//

#import "NUIPreprocessor.h"

@implementation NUIPreprocessor

+ (NSString *)preprocessFileAtPath:(NSString *)path {
NSString *content = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:nil];
return [self processString:content
path:path
dependencies:nil
importStack:@[path]];
}

+ (NSArray *)dependenciesOfFileAtPath:(NSString *)path {
NSMutableArray *dependencies = [NSMutableArray arrayWithObject:path];
NSString *content = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:nil];
[self processString:content
path:path
dependencies:dependencies
importStack:@[path]];
return dependencies;
}

+ (NSString *)processString:(NSString *)string path:(NSString *)path dependencies:(NSMutableArray *)dependencies importStack:(NSArray *)importStack {
NSError *error = NULL;
NSUInteger pos = 0;
NSUInteger length = string.length;
NSMutableString *result = NSMutableString.string;

NSRegularExpression *importRegex = [NSRegularExpression regularExpressionWithPattern:@"@import\\s+\'(.*)\'"
options:NSRegularExpressionCaseInsensitive
error:&error];

NSRegularExpression *blockCommentRegex = [NSRegularExpression regularExpressionWithPattern:@"/\\*.*\\*/"
options:NSRegularExpressionCaseInsensitive
error:&error];

NSRegularExpression *lineCommentRegex = [NSRegularExpression regularExpressionWithPattern:@"//.*\\n"
options:NSRegularExpressionCaseInsensitive
error:&error];

while(YES) {
NSTextCheckingResult* blockCommentMatch = [blockCommentRegex firstMatchInString:string options:0 range:NSMakeRange(pos, length - pos)];
NSTextCheckingResult* lineCommentMatch = [lineCommentRegex firstMatchInString:string options:0 range:NSMakeRange(pos, length - pos)];
NSTextCheckingResult* importMatch = [importRegex firstMatchInString:string options:0 range:NSMakeRange(pos, length - pos)];

NSTextCheckingResult* match = nil;
if(blockCommentMatch) {
match = match == nil || match.range.location > blockCommentMatch.range.location ? blockCommentMatch : match;
}
if(lineCommentMatch) {
match = match == nil || match.range.location > lineCommentMatch.range.location ? lineCommentMatch : match;
}
if(importMatch) {
match = match == nil || match.range.location > importMatch.range.location ? importMatch : match;
}

if(!match) break;
if(match == importMatch) {
[result appendString:[string substringWithRange:NSMakeRange(pos, match.range.location - pos)]];
pos = match.range.location + match.range.length;

NSString *importedFileName = [string substringWithRange:(NSRange)[match rangeAtIndex:1]];
NSString* importedPath = [self pathForIncludedFile:importedFileName inSourceFile:path];
if(!importedPath) {
NSLog(@"Preprocessing error: file not found: `%@`, imported from: `%@`, skipping", importedFileName, path);
continue;
}

if([importStack containsObject:importedPath]) {
NSLog(@"Preprocessing error: circular include: `%@`, imported from: `%@`, skipping", importedFileName, importStack);
continue;
}

if(dependencies && ![dependencies containsObject:importedPath]) {
[dependencies addObject:importedPath];
}
NSString *content = [NSString stringWithContentsOfFile:importedPath encoding:NSUTF8StringEncoding error:nil];
if(!content) {
NSLog(@"Preprocessing error: could not read: `%@`, imported from: `%@`, skipping", importedFileName, path);
continue;
}

[result appendString:[self processString:content path:importedPath dependencies:dependencies importStack:[importStack arrayByAddingObject:importedPath]]];
} else {
// drop comments
[result appendString:[string substringWithRange:NSMakeRange(pos, match.range.location - pos)]];
pos = match.range.location + match.range.length;
}
};

[result appendString:[string substringWithRange:NSMakeRange(pos, string.length - pos)]];
return result;
}

+ (NSString *)pathForIncludedFile:(NSString *)includedFile inSourceFile:(NSString *)sourceFilePath {
NSString *dir = [sourceFilePath stringByDeletingLastPathComponent];
NSString *proposedPath = [dir stringByAppendingPathComponent:includedFile];
if([NSFileManager.defaultManager fileExistsAtPath:proposedPath]) return proposedPath;
return [[NSBundle mainBundle] pathForResource:includedFile ofType:nil];
}

@end
37 changes: 29 additions & 8 deletions NUI/Core/NUIRenderer.m
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

#import "NUIRenderer.h"
#import "UIProgressView+NUI.h"
#import "NUIPreprocessor.h"

@implementation NUIRenderer

Expand Down Expand Up @@ -331,13 +332,7 @@ + (NUIRenderer*)getInstance
@synchronized(self) {
if (gInstance == nil) {
gInstance = [NUIRenderer new];
if ([NUISettings autoUpdateIsEnabled]) {
[NUIFileMonitor watch:[NUISettings autoUpdatePath] withCallback:^(){
dispatch_async(dispatch_get_main_queue(), ^{
[self stylesheetFileChanged];
});
}];
}
[self resetFileMonitor];
}
}
return gInstance;
Expand All @@ -355,9 +350,35 @@ + (void)orientationDidChange:(NSNotification *)notification

+ (void)stylesheetFileChanged
{
[NUISettings loadStylesheetByPath:[NUISettings autoUpdatePath]];
@try {
[NUISettings loadStylesheetByPath:[NUISettings autoUpdatePath]];
} @catch (NSException *exception) {
NSLog(@"Error: %@", exception);
}
[NUIRenderer rerender];
[CATransaction flush];
dispatch_async(dispatch_get_main_queue(), ^{
[self resetFileMonitor];
});
}

+ (void)resetFileMonitor {
if ([NUISettings autoUpdateIsEnabled]) {
NSArray *pathesToMonitor = @[[NUISettings autoUpdatePath]];
@try {
pathesToMonitor = [NUIPreprocessor dependenciesOfFileAtPath:[NUISettings autoUpdatePath]];
} @catch (NSException *exception) {
NSLog(@"Error: %@", exception);
}

for(NSString *path in pathesToMonitor) {
[NUIFileMonitor watch:path withCallback:^(){
dispatch_async(dispatch_get_main_queue(), ^{
[self stylesheetFileChanged];
});
}];
}
}
}

@end
11 changes: 3 additions & 8 deletions NUI/Core/NUIStyleParser.m
Original file line number Diff line number Diff line change
Expand Up @@ -22,21 +22,20 @@
#import "NUIRenderer.h"
#import "NUISettings.h"
#import "NUIDefinition.h"
#import "NUIPreprocessor.h"

@implementation NUIStyleParser

- (NSMutableDictionary*)getStylesFromFile:(NSString*)fileName
{
NSString* path = [[NSBundle mainBundle] pathForResource:fileName ofType:@"nss"];
NSAssert1(path != nil, @"File \"%@\" does not exist", fileName);
NSString* content = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:nil];
NUIStyleSheet *styleSheet = [self parse:content];
return [self consolidateRuleSets:styleSheet];
return [self getStylesFromPath:path];
}

- (NSMutableDictionary*)getStylesFromPath:(NSString*)path
{
NSString* content = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:nil];
NSString* content = [NUIPreprocessor preprocessFileAtPath:path];
NUIStyleSheet *styleSheet = [self parse:content];
return [self consolidateRuleSets:styleSheet];
}
Expand Down Expand Up @@ -119,10 +118,6 @@ - (NUIStyleSheet *)parse:(NSString *)styles


[tokeniser addTokenRecogniser:[NUIPWhiteSpaceRecogniser whiteSpaceRecogniser]];
[tokeniser addTokenRecogniser:[NUIPQuotedRecogniser quotedRecogniserWithStartQuote:@"/*"
endQuote:@"*/"
name:@"Comment"]];

[tokeniser addTokenRecogniser:[NUIPKeywordRecogniser recogniserForKeyword:@"@media"]];
[tokeniser addTokenRecogniser:[NUIPKeywordRecogniser recogniserForKeyword:@"and"]];

Expand Down
2 changes: 1 addition & 1 deletion NUI/Core/Parser/NUITokeniserDelegate.m
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ - (BOOL)tokeniser:(NUIPTokeniser *)tokeniser shouldConsumeToken:(NUIPToken *)tok

- (void)tokeniser:(NUIPTokeniser *)tokeniser requestsToken:(NUIPToken *)token pushedOntoStream:(NUIPTokenStream *)stream
{
if ([token isWhiteSpaceToken] || [[token name] isEqualToString:@"Comment"])
if ([token isWhiteSpaceToken])
return;

if ([token isIdentifierToken]) {
Expand Down