{ 130
-        print(index)
131 130
         currIndex = index
132 131
         _hasGetPrice.accept(false)
133 132
         itemViewModel.item.accept(_items.value[index])

+ 15 - 12
PaiAi/PaiaiUIKit/Reusable/UIKit/NavigationController/NavigationController.swift

@@ -11,10 +11,10 @@ import UIKit
11 11
 public class NavigationController: UINavigationController {
12 12
     
13 13
     private var operation: Operation = .none
14
-    private var barConfigures: [UIViewController?: NavigationBarConfiguration] = [:]
14
+    private var barConfigures = [UIViewController: NavigationBarConfiguration]()
15 15
     
16
-    private var _fromFakeBar = UIToolbar()
17
-    private var _toFakeBar = UIToolbar()
16
+    private var _fromFakeBar: UIToolbar? = nil
17
+    private var _toFakeBar: UIToolbar? = nil
18 18
     
19 19
     override public init(rootViewController: UIViewController) {
20 20
         super.init(navigationBarClass: NavigationBar.classForCoder(), toolbarClass: nil)
@@ -73,24 +73,27 @@ fileprivate extension NavigationController {
73 73
     func setFromFakeNavigationBar(for from: UIViewController) {
74 74
         if let navBarFrame = from.getFakeBarFrame(for: navigationBar) {
75 75
             _fromFakeBar = UIToolbar(configure: barConfigures[from] ?? .default)
76
-            _fromFakeBar.delegate = self
77
-            _fromFakeBar.frame = navBarFrame
78
-            from.view.addSubview(_fromFakeBar)
76
+            _fromFakeBar?.delegate = self
77
+            _fromFakeBar?.frame = navBarFrame
78
+            from.view.addSubview(_fromFakeBar!)
79 79
         }
80 80
     }
81 81
     
82 82
     func setToFakeNavigationBar(for to: UIViewController) {
83 83
         if let navBarFrame = to.getFakeBarFrame(for: navigationBar) {
84 84
             _toFakeBar = UIToolbar(configure: barConfigures[to] ?? .default)
85
-            _toFakeBar.delegate = self
86
-            _toFakeBar.frame = navBarFrame
87
-            to.view.addSubview(_toFakeBar)
85
+            _toFakeBar?.delegate = self
86
+            _toFakeBar?.frame = navBarFrame
87
+            to.view.addSubview(_toFakeBar!)
88 88
         }
89 89
     }
90 90
     
91 91
     func clearFake() {
92
-        _fromFakeBar.removeFromSuperview()
93
-        _toFakeBar.removeFromSuperview()
92
+        _fromFakeBar?.removeFromSuperview()
93
+        _toFakeBar?.removeFromSuperview()
94
+        
95
+        _fromFakeBar = nil
96
+        _toFakeBar = nil
94 97
         
95 98
         guard let from = transitionCoordinator?.viewController(forKey: .from),
96 99
             operation == .pop else { return }
@@ -130,7 +133,7 @@ extension NavigationController: UINavigationControllerDelegate {
130 133
                 vc = context.viewController(forKey: .to)
131 134
             }
132 135
             self.navigationBar.getBarBackground()?.alpha = 1
133
-            self.navigationBar.apply(for: self.barConfigures[vc] ?? .default)
136
+            self.navigationBar.apply(for: self.barConfigures[vc!] ?? .default)
134 137
             self.clearFake()
135 138
         })
136 139
     }

+ 0 - 1
PaiAi/Paiai_iOS/App/AppCoordinator.swift

@@ -23,7 +23,6 @@ public final class AppCoordinator: BaseCoordinator<Void> {
23 23
     public init(window: UIWindow) {
24 24
         self.window = window
25 25
         self.containerViewController = ContainerViewController()
26
-
27 26
         super.init(navigationController: NavigationController(rootViewController: containerViewController),
28 27
                    viewController: containerViewController)
29 28
     }

+ 5 - 0
PaiAi/Paiai_iOS/App/Group/GroupViewController.swift

@@ -82,6 +82,11 @@ final class GroupViewController: UIViewController {
82 82
         collectionView.startRefreshing(at: .top)
83 83
     }
84 84
 
85
+    override func removeFromParent() {
86
+        super.removeFromParent()
87
+        print(self)
88
+    }
89
+    
85 90
     deinit {
86 91
         collectionView.removeAllPullToRefresh()
87 92
     }

+ 1 - 1
PaiAi/Paiai_iOS/App/Home/HomeCoordinator.swift

@@ -29,7 +29,7 @@ class HomeCoordinator: BaseCoordinator<Void> {
29 29
     @discardableResult
30 30
     override func start() -> Observable<Void> {
31 31
         homeViewController.viewModel.delegate = self
32
-
32
+        deallocatedDispose.dispose()
33 33
         return Observable.never()
34 34
     }
35 35
 }

+ 17 - 25
PaiAi/Paiai_iOS/App/Home/HomeViewController.swift

@@ -10,7 +10,7 @@ import RxCocoa
10 10
 import RxDataSources
11 11
 import PaiaiDataKit
12 12
 import PaiaiUIKit
13
-import PullToRefresh
13
+import ESPullToRefresh
14 14
 
15 15
 final class HomeViewController: UIViewController {
16 16
 
@@ -20,22 +20,14 @@ final class HomeViewController: UIViewController {
20 20
     // MARK: data property
21 21
     fileprivate let disposeBag = DisposeBag()
22 22
 
23
-    internal var viewModel: HomeViewModel!
24
-    internal var userInfoViewModel: UserInfoViewModel!
23
+    var viewModel: HomeViewModel!
24
+    var userInfoViewModel: UserInfoViewModel!
25 25
 
26 26
     override func viewDidLoad() {
27 27
         super.viewDidLoad()
28 28
         initalize()
29 29
     }
30 30
 
31
-    override func viewDidAppear(_ animated: Bool) {
32
-        super.viewDidAppear(animated)
33
-    }
34
-    
35
-    override func viewDidDisappear(_ animated: Bool) {
36
-        super.viewDidDisappear(animated)
37
-    }
38
-
39 31
     func initalize() {
40 32
         collectionView.register(UINib(nibName: "PhotoCell",
41 33
                                       bundle: Bundle(identifier: "com.Paiai-iOS")),
@@ -51,22 +43,22 @@ final class HomeViewController: UIViewController {
51 43
     }
52 44
 
53 45
     private func setupReloadControl() {
54
-        collectionView.addPullToRefresh(PullToRefresh()) {
46
+        collectionView.es.addPullToRefresh {
55 47
             [unowned self] in
56 48
             self.viewModel.reload()
57 49
         }
58 50
     }
59 51
 
60 52
     private func setupLoadingControl() {
61
-        collectionView.addPullToRefresh(PullToRefresh(position: .bottom)) {
62
-            [weak self] in
63
-            guard let `self` = self else { return }
53
+        collectionView.es.addInfiniteScrolling {
54
+            [unowned self] in
64 55
             self.viewModel.preload()
65 56
         }
66 57
     }
67 58
 
68 59
     deinit {
69
-        collectionView.removeAllPullToRefresh()
60
+        collectionView.es.removeRefreshFooter()
61
+        collectionView.es.removeRefreshHeader()
70 62
     }
71 63
 }
72 64
 
@@ -100,11 +92,12 @@ fileprivate extension HomeViewController {
100 92
     func bindViewModelToRefreshing() {
101 93
         viewModel.isLoading
102 94
             .asDriver(onErrorJustReturn: true)
103
-            .drive(onNext: {[unowned self] flag in
95
+            .drive(onNext: {[weak self] flag in
96
+                guard let `self` = self else { return }
104 97
                 if flag {
105
-                    self.collectionView.endRefreshing(at: .top)
98
+                    self.collectionView.es.stopPullToRefresh()
106 99
                 } else {
107
-                    self.collectionView.endRefreshing(at: .bottom)
100
+                    self.collectionView.es.stopLoadingMore()
108 101
                 }
109 102
             }).disposed(by: disposeBag)
110 103
     }
@@ -114,12 +107,11 @@ fileprivate extension HomeViewController {
114 107
     }
115 108
 
116 109
     func bindUserInfoViewModelToView() {
117
-        userInfoViewModel.isLoggedIn
118
-            .asDriver(onErrorJustReturn: ())
119
-            .drive(onNext: {[unowned self] _ in
120
-                self.viewModel.clear()
121
-                self.collectionView.startRefreshing(at: .top)
122
-            }).disposed(by: disposeBag)
110
+        userInfoViewModel.isLoggedIn.subscribe({[weak self] _ in
111
+            guard let `self` = self else { return }
112
+            self.viewModel.clear()
113
+            self.collectionView.startRefreshing(at: .top)
114
+        }).disposed(by: disposeBag)
123 115
     }
124 116
 
125 117
     func bindViewModelToCollectionView() {

+ 1 - 0
PaiAi/Paiai_iOS/App/Message/MessageCoordinator.swift

@@ -22,6 +22,7 @@ class MessageCoordinator: BaseCoordinator<Void> {
22 22
 
23 23
     override func start() -> Observable<Void> {
24 24
         messageViewController.viewModel.delegate = self
25
+        deallocatedDispose.dispose()
25 26
         return Observable.never()
26 27
     }
27 28
 }

+ 14 - 4
PaiAi/Paiai_iOS/App/Mine/MineAboutViewController.swift

@@ -7,8 +7,8 @@
7 7
 //
8 8
 
9 9
 import UIKit
10
-import PaiaiDataKit
11 10
 import PaiaiUIKit
11
+
12 12
 import RxSwift
13 13
 
14 14
 final class MineAboutViewController: UIViewController {
@@ -30,6 +30,15 @@ final class MineAboutViewController: UIViewController {
30 30
         versionLabel.text = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String
31 31
         bindGestures()
32 32
     }
33
+    
34
+    override func viewDidDisappear(_ animated: Bool) {
35
+        super.viewDidDisappear(animated)
36
+        
37
+    }
38
+    
39
+    deinit {
40
+        print("deinit")
41
+    }
33 42
 }
34 43
 
35 44
 fileprivate extension MineAboutViewController {
@@ -42,7 +51,7 @@ fileprivate extension MineAboutViewController {
42 51
     func bindGestureToContactUsAction() {
43 52
         contactUsBtn.rx.tap
44 53
             .asObservable()
45
-            .subscribe { (_) in
54
+            .subscribe { [unowned self] _ in
46 55
                 let webVC = WebViewController(title: "联系我们",
47 56
                                               path: "https://pai.ai/page/contact_us")
48 57
                 self.navigationController?.pushViewController(webVC)
@@ -52,7 +61,7 @@ fileprivate extension MineAboutViewController {
52 61
     func bindGestureToScoreAction() {
53 62
         scoreBtn.rx.tap
54 63
             .asObservable()
55
-            .subscribe { (_) in
64
+            .subscribe {  _ in
56 65
                 guard let url = URL(string: "https://itunes.apple.com/cn/app/pai-aipaiai/id1163960351?mt=8") else {
57 66
                     return
58 67
                 }
@@ -63,7 +72,7 @@ fileprivate extension MineAboutViewController {
63 72
     func bindGestureToUserAgreementAction() {
64 73
         userAgreementBtn.rx.tap
65 74
             .asObservable()
66
-            .subscribe { (_) in
75
+            .subscribe { [unowned self] _ in
67 76
                 let webVC = WebViewController(title: "用户协议",
68 77
                                               path: "https://pai.ai/page/user_agreement")
69 78
                 self.navigationController?.pushViewController(webVC)
@@ -78,3 +87,4 @@ extension MineAboutViewController: Storyboarded {
78 87
         return UIStoryboard.mine.instantiateViewController(type: MineAboutViewController.self)
79 88
     }
80 89
 }
90
+

+ 5 - 7
PaiAi/Paiai_iOS/App/Mine/MineCoordinator.swift

@@ -25,8 +25,6 @@ class MineCoordinator: BaseCoordinator<Void> {
25 25
         mineViewController.delegate = self
26 26
         return didCancel
27 27
     }
28
-
29
-    override func listenDeallocate() {}
30 28
 }
31 29
 
32 30
 extension MineCoordinator: MineViewControllerDelegate {
@@ -46,7 +44,7 @@ extension MineCoordinator: MineViewControllerDelegate {
46 44
 
47 45
     func didSelect(_ item: MineItem) {
48 46
         mineViewController.dismissController()
49
-
47
+        deallocatedDispose.dispose()
50 48
         let vc: UIViewController
51 49
         switch item {
52 50
         case .group:
@@ -58,8 +56,8 @@ extension MineCoordinator: MineViewControllerDelegate {
58 56
         case .about:
59 57
             vc = makeMineAboutViewController()
60 58
         }
61
-
62
-        vc.rx.deallocated.subscribe(onNext: { _ in
59
+        
60
+        vc.rx.deallocating.subscribe(onNext: { _ in
63 61
             self.didCancel.onNext(())
64 62
         }).disposed(by: disposeBag)
65 63
     }
@@ -103,8 +101,8 @@ fileprivate extension MineCoordinator {
103 101
 
104 102
     func makeMineAboutViewController() -> MineAboutViewController {
105 103
         let vc = MineAboutViewController.instantiate()
106
-        navigationController.pushViewController(vc)
107
-
104
+        navigationController.pushViewController(vc, animated: true)
105
+        print(navigationController)
108 106
         return vc
109 107
     }
110 108
 

+ 10 - 11
PaiAi/Paiai_iOS/Reusable/BaseCoordinator.swift

@@ -7,7 +7,7 @@
7 7
 //
8 8
 
9 9
 import RxSwift
10
-import Foundation
10
+import UIKit
11 11
 
12 12
 public class BaseCoordinator<ResultType> {
13 13
 
@@ -15,6 +15,7 @@ public class BaseCoordinator<ResultType> {
15 15
 
16 16
     let disposeBag = DisposeBag()
17 17
     var didCancel = PublishSubject<Void>()
18
+    var deallocatedDispose = Disposables.create()
18 19
     var navigationController: UINavigationController
19 20
     var viewController: UIViewController
20 21
 
@@ -25,7 +26,13 @@ public class BaseCoordinator<ResultType> {
25 26
     init(navigationController: UINavigationController, viewController: UIViewController) {
26 27
         self.viewController = viewController
27 28
         self.navigationController = navigationController
28
-        listenDeallocate()
29
+        
30
+        deallocatedDispose = viewController.rx.viewDidDisappear.subscribe(onNext: {[weak self] _ in
31
+            guard let `self` = self else { return }
32
+            if !self.navigationController.viewControllers.contains(viewController) {
33
+                self.didCancel.onNext(())
34
+            }
35
+        })
29 36
     }
30 37
 
31 38
     private func store<T>(coordinator: BaseCoordinator<T>) {
@@ -33,6 +40,7 @@ public class BaseCoordinator<ResultType> {
33 40
     }
34 41
 
35 42
     private func free<T>(coordinator: BaseCoordinator<T>) {
43
+        print(coordinator)
36 44
         childCoordinators[coordinator.identifier] = nil
37 45
     }
38 46
 
@@ -48,13 +56,4 @@ public class BaseCoordinator<ResultType> {
48 56
     func start() -> Observable<ResultType> {
49 57
         fatalError("Start method should be implemented.")
50 58
     }
51
-
52
-    func listenDeallocate() {
53
-        navigationController.rx.willShow.subscribe(onNext: {[weak self] (_, _) in
54
-            guard let `self` = self else { return }
55
-            if !self.navigationController.viewControllers.contains(self.viewController) {
56
-                self.didCancel.onNext(())
57
-            }
58
-        }).disposed(by: disposeBag)
59
-    }
60 59
 }

adminSystem - Gogs: Go Git Service

暂无描述

tokenize.js 22KB

    var Marker = require('./marker'); var Token = require('./token'); var formatPosition = require('../utils/format-position'); var Level = { BLOCK: 'block', COMMENT: 'comment', DOUBLE_QUOTE: 'double-quote', RULE: 'rule', SINGLE_QUOTE: 'single-quote' }; var AT_RULES = [ '@charset', '@import' ]; var BLOCK_RULES = [ '@-moz-document', '@document', '@-moz-keyframes', '@-ms-keyframes', '@-o-keyframes', '@-webkit-keyframes', '@keyframes', '@media', '@supports' ]; var PAGE_MARGIN_BOXES = [ '@bottom-center', '@bottom-left', '@bottom-left-corner', '@bottom-right', '@bottom-right-corner', '@left-bottom', '@left-middle', '@left-top', '@right-bottom', '@right-middle', '@right-top', '@top-center', '@top-left', '@top-left-corner', '@top-right', '@top-right-corner' ]; var EXTRA_PAGE_BOXES = [ '@footnote', '@footnotes', '@left', '@page-float-bottom', '@page-float-top', '@right' ]; var REPEAT_PATTERN = /^\[\s{0,31}\d+\s{0,31}\]$/; var RULE_WORD_SEPARATOR_PATTERN = /[\s\(]/; var TAIL_BROKEN_VALUE_PATTERN = /[\s|\}]*$/; function tokenize(source, externalContext) { var internalContext = { level: Level.BLOCK, position: { source: externalContext.source || undefined, line: 1, column: 0, index: 0 } }; return intoTokens(source, externalContext, internalContext, false); } function intoTokens(source, externalContext, internalContext, isNested) { var allTokens = []; var newTokens = allTokens; var lastToken; var ruleToken; var ruleTokens = []; var propertyToken; var metadata; var metadatas = []; var level = internalContext.level; var levels = []; var buffer = []; var buffers = []; var serializedBuffer; var roundBracketLevel = 0; var isQuoted; var isSpace; var isNewLineNix; var isNewLineWin; var isCommentStart; var wasCommentStart = false; var isCommentEnd; var wasCommentEnd = false; var isCommentEndMarker; var isEscaped; var wasEscaped = false; var seekingValue = false; var seekingPropertyBlockClosing = false; var position = internalContext.position; for (; position.index < source.length; position.index++) { var character = source[position.index]; isQuoted = level == Level.SINGLE_QUOTE || level == Level.DOUBLE_QUOTE; isSpace = character == Marker.SPACE || character == Marker.TAB; isNewLineNix = character == Marker.NEW_LINE_NIX; isNewLineWin = character == Marker.NEW_LINE_NIX && source[position.index - 1] == Marker.NEW_LINE_WIN; isCommentStart = !wasCommentEnd && level != Level.COMMENT && !isQuoted && character == Marker.ASTERISK && source[position.index - 1] == Marker.FORWARD_SLASH; isCommentEndMarker = !wasCommentStart && !isQuoted && character == Marker.FORWARD_SLASH && source[position.index - 1] == Marker.ASTERISK; isCommentEnd = level == Level.COMMENT && isCommentEndMarker; roundBracketLevel = Math.max(roundBracketLevel, 0); metadata = buffer.length === 0 ? [position.line, position.column, position.source] : metadata; if (isEscaped) { // previous character was a backslash buffer.push(character); } else if (!isCommentEnd && level == Level.COMMENT) { buffer.push(character); } else if (isCommentStart && (level == Level.BLOCK || level == Level.RULE) && buffer.length > 1) { // comment start within block preceded by some content, e.g. div/*<-- metadatas.push(metadata); buffer.push(character); buffers.push(buffer.slice(0, buffer.length - 2)); buffer = buffer.slice(buffer.length - 2); metadata = [position.line, position.column - 1, position.source]; levels.push(level); level = Level.COMMENT; } else if (isCommentStart) { // comment start, e.g. /*<-- levels.push(level); level = Level.COMMENT; buffer.push(character); } else if (isCommentEnd) { // comment end, e.g. /* comment */<-- serializedBuffer = buffer.join('').trim() + character; lastToken = [Token.COMMENT, serializedBuffer, [originalMetadata(metadata, serializedBuffer, externalContext)]]; newTokens.push(lastToken); level = levels.pop(); metadata = metadatas.pop() || null; buffer = buffers.pop() || []; } else if (isCommentEndMarker && source[position.index + 1] != Marker.ASTERISK) { externalContext.warnings.push('Unexpected \'*/\' at ' + formatPosition([position.line, position.column, position.source]) + '.'); buffer = []; } else if (character == Marker.SINGLE_QUOTE && !isQuoted) { // single quotation start, e.g. a[href^='https<-- levels.push(level); level = Level.SINGLE_QUOTE; buffer.push(character); } else if (character == Marker.SINGLE_QUOTE && level == Level.SINGLE_QUOTE) { // single quotation end, e.g. a[href^='https'<-- level = levels.pop(); buffer.push(character); } else if (character == Marker.DOUBLE_QUOTE && !isQuoted) { // double quotation start, e.g. a[href^="<-- levels.push(level); level = Level.DOUBLE_QUOTE; buffer.push(character); } else if (character == Marker.DOUBLE_QUOTE && level == Level.DOUBLE_QUOTE) { // double quotation end, e.g. a[href^="https"<-- level = levels.pop(); buffer.push(character); } else if (!isCommentStart && !isCommentEnd && character != Marker.CLOSE_ROUND_BRACKET && character != Marker.OPEN_ROUND_BRACKET && level != Level.COMMENT && !isQuoted && roundBracketLevel > 0) { // character inside any function, e.g. hsla(.<-- buffer.push(character); } else if (character == Marker.OPEN_ROUND_BRACKET && !isQuoted && level != Level.COMMENT && !seekingValue) { // round open bracket, e.g. @import url(<-- buffer.push(character); roundBracketLevel++; } else if (character == Marker.CLOSE_ROUND_BRACKET && !isQuoted && level != Level.COMMENT && !seekingValue) { // round open bracket, e.g. @import url(test.css)<-- buffer.push(character); roundBracketLevel--; } else if (character == Marker.SEMICOLON && level == Level.BLOCK && buffer[0] == Marker.AT) { // semicolon ending rule at block level, e.g. @import '...';<-- serializedBuffer = buffer.join('').trim(); allTokens.push([Token.AT_RULE, serializedBuffer, [originalMetadata(metadata, serializedBuffer, externalContext)]]); buffer = []; } else if (character == Marker.COMMA && level == Level.BLOCK && ruleToken) { // comma separator at block level, e.g. a,div,<-- serializedBuffer = buffer.join('').trim(); ruleToken[1].push([tokenScopeFrom(ruleToken[0]), serializedBuffer, [originalMetadata(metadata, serializedBuffer, externalContext, ruleToken[1].length)]]); buffer = []; } else if (character == Marker.COMMA && level == Level.BLOCK && tokenTypeFrom(buffer) == Token.AT_RULE) { // comma separator at block level, e.g. @import url(...) screen,<-- // keep iterating as end semicolon will create the token buffer.push(character); } else if (character == Marker.COMMA && level == Level.BLOCK) { // comma separator at block level, e.g. a,<-- ruleToken = [tokenTypeFrom(buffer), [], []]; serializedBuffer = buffer.join('').trim(); ruleToken[1].push([tokenScopeFrom(ruleToken[0]), serializedBuffer, [originalMetadata(metadata, serializedBuffer, externalContext, 0)]]); buffer = []; } else if (character == Marker.OPEN_CURLY_BRACKET && level == Level.BLOCK && ruleToken && ruleToken[0] == Token.NESTED_BLOCK) { // open brace opening at-rule at block level, e.g. @media{<-- serializedBuffer = buffer.join('').trim(); ruleToken[1].push([Token.NESTED_BLOCK_SCOPE, serializedBuffer, [originalMetadata(metadata, serializedBuffer, externalContext)]]); allTokens.push(ruleToken); levels.push(level); position.column++; position.index++; buffer = []; ruleToken[2] = intoTokens(source, externalContext, internalContext, true); ruleToken = null; } else if (character == Marker.OPEN_CURLY_BRACKET && level == Level.BLOCK && tokenTypeFrom(buffer) == Token.NESTED_BLOCK) { // open brace opening at-rule at block level, e.g. @media{<-- serializedBuffer = buffer.join('').trim(); ruleToken = ruleToken || [Token.NESTED_BLOCK, [], []]; ruleToken[1].push([Token.NESTED_BLOCK_SCOPE, serializedBuffer, [originalMetadata(metadata, serializedBuffer, externalContext)]]); allTokens.push(ruleToken); levels.push(level); position.column++; position.index++; buffer = []; ruleToken[2] = intoTokens(source, externalContext, internalContext, true); ruleToken = null; } else if (character == Marker.OPEN_CURLY_BRACKET && level == Level.BLOCK) { // open brace opening rule at block level, e.g. div{<-- serializedBuffer = buffer.join('').trim(); ruleToken = ruleToken || [tokenTypeFrom(buffer), [], []]; ruleToken[1].push([tokenScopeFrom(ruleToken[0]), serializedBuffer, [originalMetadata(metadata, serializedBuffer, externalContext, ruleToken[1].length)]]); newTokens = ruleToken[2]; allTokens.push(ruleToken); levels.push(level); level = Level.RULE; buffer = []; } else if (character == Marker.OPEN_CURLY_BRACKET && level == Level.RULE && seekingValue) { // open brace opening rule at rule level, e.g. div{--variable:{<-- ruleTokens.push(ruleToken); ruleToken = [Token.PROPERTY_BLOCK, []]; propertyToken.push(ruleToken); newTokens = ruleToken[1]; levels.push(level); level = Level.RULE; seekingValue = false; } else if (character == Marker.OPEN_CURLY_BRACKET && level == Level.RULE && isPageMarginBox(buffer)) { // open brace opening page-margin box at rule level, e.g. @page{@top-center{<-- serializedBuffer = buffer.join('').trim(); ruleTokens.push(ruleToken); ruleToken = [Token.AT_RULE_BLOCK, [], []]; ruleToken[1].push([Token.AT_RULE_BLOCK_SCOPE, serializedBuffer, [originalMetadata(metadata, serializedBuffer, externalContext)]]); newTokens.push(ruleToken); newTokens = ruleToken[2]; levels.push(level); level = Level.RULE; buffer = []; } else if (character == Marker.COLON && level == Level.RULE && !seekingValue) { // colon at rule level, e.g. a{color:<-- serializedBuffer = buffer.join('').trim(); propertyToken = [Token.PROPERTY, [Token.PROPERTY_NAME, serializedBuffer, [originalMetadata(metadata, serializedBuffer, externalContext)]]]; newTokens.push(propertyToken); seekingValue = true; buffer = []; } else if (character == Marker.SEMICOLON && level == Level.RULE && propertyToken && ruleTokens.length > 0 && buffer.length > 0 && buffer[0] == Marker.AT) { // semicolon at rule level for at-rule, e.g. a{--color:{@apply(--other-color);<-- serializedBuffer = buffer.join('').trim(); ruleToken[1].push([Token.AT_RULE, serializedBuffer, [originalMetadata(metadata, serializedBuffer, externalContext)]]); buffer = []; } else if (character == Marker.SEMICOLON && level == Level.RULE && propertyToken && buffer.length > 0) { // semicolon at rule level, e.g. a{color:red;<-- serializedBuffer = buffer.join('').trim(); propertyToken.push([Token.PROPERTY_VALUE, serializedBuffer, [originalMetadata(metadata, serializedBuffer, externalContext)]]); propertyToken = null; seekingValue = false; buffer = []; } else if (character == Marker.SEMICOLON && level == Level.RULE && propertyToken && buffer.length === 0) { // semicolon after bracketed value at rule level, e.g. a{color:rgb(...);<-- propertyToken = null; seekingValue = false; } else if (character == Marker.SEMICOLON && level == Level.RULE && buffer.length > 0 && buffer[0] == Marker.AT) { // semicolon for at-rule at rule level, e.g. a{@apply(--variable);<-- serializedBuffer = buffer.join(''); newTokens.push([Token.AT_RULE, serializedBuffer, [originalMetadata(metadata, serializedBuffer, externalContext)]]); seekingValue = false; buffer = []; } else if (character == Marker.SEMICOLON && level == Level.RULE && seekingPropertyBlockClosing) { // close brace after a property block at rule level, e.g. a{--custom:{color:red;};<-- seekingPropertyBlockClosing = false; buffer = []; } else if (character == Marker.SEMICOLON && level == Level.RULE && buffer.length === 0) { // stray semicolon at rule level, e.g. a{;<-- // noop } else if (character == Marker.CLOSE_CURLY_BRACKET && level == Level.RULE && propertyToken && seekingValue && buffer.length > 0 && ruleTokens.length > 0) { // close brace at rule level, e.g. a{--color:{color:red}<-- serializedBuffer = buffer.join(''); propertyToken.push([Token.PROPERTY_VALUE, serializedBuffer, [originalMetadata(metadata, serializedBuffer, externalContext)]]); propertyToken = null; ruleToken = ruleTokens.pop(); newTokens = ruleToken[2]; level = levels.pop(); seekingValue = false; buffer = []; } else if (character == Marker.CLOSE_CURLY_BRACKET && level == Level.RULE && propertyToken && buffer.length > 0 && buffer[0] == Marker.AT && ruleTokens.length > 0) { // close brace at rule level for at-rule, e.g. a{--color:{@apply(--other-color)}<-- serializedBuffer = buffer.join(''); ruleToken[1].push([Token.AT_RULE, serializedBuffer, [originalMetadata(metadata, serializedBuffer, externalContext)]]); propertyToken = null; ruleToken = ruleTokens.pop(); newTokens = ruleToken[2]; level = levels.pop(); seekingValue = false; buffer = []; } else if (character == Marker.CLOSE_CURLY_BRACKET && level == Level.RULE && propertyToken && ruleTokens.length > 0) { // close brace at rule level after space, e.g. a{--color:{color:red }<-- propertyToken = null; ruleToken = ruleTokens.pop(); newTokens = ruleToken[2]; level = levels.pop(); seekingValue = false; } else if (character == Marker.CLOSE_CURLY_BRACKET && level == Level.RULE && propertyToken && buffer.length > 0) { // close brace at rule level, e.g. a{color:red}<-- serializedBuffer = buffer.join(''); propertyToken.push([Token.PROPERTY_VALUE, serializedBuffer, [originalMetadata(metadata, serializedBuffer, externalContext)]]); propertyToken = null; ruleToken = ruleTokens.pop(); newTokens = allTokens; level = levels.pop(); seekingValue = false; buffer = []; } else if (character == Marker.CLOSE_CURLY_BRACKET && level == Level.RULE && buffer.length > 0 && buffer[0] == Marker.AT) { // close brace after at-rule at rule level, e.g. a{@apply(--variable)}<-- propertyToken = null; ruleToken = null; serializedBuffer = buffer.join('').trim(); newTokens.push([Token.AT_RULE, serializedBuffer, [originalMetadata(metadata, serializedBuffer, externalContext)]]); newTokens = allTokens; level = levels.pop(); seekingValue = false; buffer = []; } else if (character == Marker.CLOSE_CURLY_BRACKET && level == Level.RULE && levels[levels.length - 1] == Level.RULE) { // close brace after a property block at rule level, e.g. a{--custom:{color:red;}<-- propertyToken = null; ruleToken = ruleTokens.pop(); newTokens = ruleToken[2]; level = levels.pop(); seekingValue = false; seekingPropertyBlockClosing = true; buffer = []; } else if (character == Marker.CLOSE_CURLY_BRACKET && level == Level.RULE) { // close brace after a rule, e.g. a{color:red;}<-- propertyToken = null; ruleToken = null; newTokens = allTokens; level = levels.pop(); seekingValue = false; } else if (character == Marker.CLOSE_CURLY_BRACKET && level == Level.BLOCK && !isNested && position.index <= source.length - 1) { // stray close brace at block level, e.g. a{color:red}color:blue}<-- externalContext.warnings.push('Unexpected \'}\' at ' + formatPosition([position.line, position.column, position.source]) + '.'); buffer.push(character); } else if (character == Marker.CLOSE_CURLY_BRACKET && level == Level.BLOCK) { // close brace at block level, e.g. @media screen {...}<-- break; } else if (character == Marker.OPEN_ROUND_BRACKET && level == Level.RULE && seekingValue) { // round open bracket, e.g. a{color:hsla(<-- buffer.push(character); roundBracketLevel++; } else if (character == Marker.CLOSE_ROUND_BRACKET && level == Level.RULE && seekingValue && roundBracketLevel == 1) { // round close bracket, e.g. a{color:hsla(0,0%,0%)<-- buffer.push(character); serializedBuffer = buffer.join('').trim(); propertyToken.push([Token.PROPERTY_VALUE, serializedBuffer, [originalMetadata(metadata, serializedBuffer, externalContext)]]); roundBracketLevel--; buffer = []; } else if (character == Marker.CLOSE_ROUND_BRACKET && level == Level.RULE && seekingValue) { // round close bracket within other brackets, e.g. a{width:calc((10rem / 2)<-- buffer.push(character); roundBracketLevel--; } else if (character == Marker.FORWARD_SLASH && source[position.index + 1] != Marker.ASTERISK && level == Level.RULE && seekingValue && buffer.length > 0) { // forward slash within a property, e.g. a{background:url(image.png) 0 0/<-- serializedBuffer = buffer.join('').trim(); propertyToken.push([Token.PROPERTY_VALUE, serializedBuffer, [originalMetadata(metadata, serializedBuffer, externalContext)]]); propertyToken.push([Token.PROPERTY_VALUE, character, [[position.line, position.column, position.source]]]); buffer = []; } else if (character == Marker.FORWARD_SLASH && source[position.index + 1] != Marker.ASTERISK && level == Level.RULE && seekingValue) { // forward slash within a property after space, e.g. a{background:url(image.png) 0 0 /<-- propertyToken.push([Token.PROPERTY_VALUE, character, [[position.line, position.column, position.source]]]); buffer = []; } else if (character == Marker.COMMA && level == Level.RULE && seekingValue && buffer.length > 0) { // comma within a property, e.g. a{background:url(image.png),<-- serializedBuffer = buffer.join('').trim(); propertyToken.push([Token.PROPERTY_VALUE, serializedBuffer, [originalMetadata(metadata, serializedBuffer, externalContext)]]); propertyToken.push([Token.PROPERTY_VALUE, character, [[position.line, position.column, position.source]]]); buffer = []; } else if (character == Marker.COMMA && level == Level.RULE && seekingValue) { // comma within a property after space, e.g. a{background:url(image.png) ,<-- propertyToken.push([Token.PROPERTY_VALUE, character, [[position.line, position.column, position.source]]]); buffer = []; } else if (character == Marker.CLOSE_SQUARE_BRACKET && propertyToken && propertyToken.length > 1 && buffer.length > 0 && isRepeatToken(buffer)) { buffer.push(character); serializedBuffer = buffer.join('').trim(); propertyToken[propertyToken.length - 1][1] += serializedBuffer; buffer = []; } else if ((isSpace || (isNewLineNix && !isNewLineWin)) && level == Level.RULE && seekingValue && propertyToken && buffer.length > 0) { // space or *nix newline within property, e.g. a{margin:0 <-- serializedBuffer = buffer.join('').trim(); propertyToken.push([Token.PROPERTY_VALUE, serializedBuffer, [originalMetadata(metadata, serializedBuffer, externalContext)]]); buffer = []; } else if (isNewLineWin && level == Level.RULE && seekingValue && propertyToken && buffer.length > 1) { // win newline within property, e.g. a{margin:0\r\n<-- serializedBuffer = buffer.join('').trim(); propertyToken.push([Token.PROPERTY_VALUE, serializedBuffer, [originalMetadata(metadata, serializedBuffer, externalContext)]]); buffer = []; } else if (isNewLineWin && level == Level.RULE && seekingValue) { // win newline buffer = []; } else if (buffer.length == 1 && isNewLineWin) { // ignore windows newline which is composed of two characters buffer.pop(); } else if (buffer.length > 0 || !isSpace && !isNewLineNix && !isNewLineWin) { // any character buffer.push(character); } wasEscaped = isEscaped; isEscaped = !wasEscaped && character == Marker.BACK_SLASH; wasCommentStart = isCommentStart; wasCommentEnd = isCommentEnd; position.line = (isNewLineWin || isNewLineNix) ? position.line + 1 : position.line; position.column = (isNewLineWin || isNewLineNix) ? 0 : position.column + 1; } if (seekingValue) { externalContext.warnings.push('Missing \'}\' at ' + formatPosition([position.line, position.column, position.source]) + '.'); } if (seekingValue && buffer.length > 0) { serializedBuffer = buffer.join('').replace(TAIL_BROKEN_VALUE_PATTERN, ''); propertyToken.push([Token.PROPERTY_VALUE, serializedBuffer, [originalMetadata(metadata, serializedBuffer, externalContext)]]); buffer = []; } if (buffer.length > 0) { externalContext.warnings.push('Invalid character(s) \'' + buffer.join('') + '\' at ' + formatPosition(metadata) + '. Ignoring.'); } return allTokens; } function originalMetadata(metadata, value, externalContext, selectorFallbacks) { var source = metadata[2]; return externalContext.inputSourceMapTracker.isTracking(source) ? externalContext.inputSourceMapTracker.originalPositionFor(metadata, value.length, selectorFallbacks) : metadata; } function tokenTypeFrom(buffer) { var isAtRule = buffer[0] == Marker.AT || buffer[0] == Marker.UNDERSCORE; var ruleWord = buffer.join('').split(RULE_WORD_SEPARATOR_PATTERN)[0]; if (isAtRule && BLOCK_RULES.indexOf(ruleWord) > -1) { return Token.NESTED_BLOCK; } else if (isAtRule && AT_RULES.indexOf(ruleWord) > -1) { return Token.AT_RULE; } else if (isAtRule) { return Token.AT_RULE_BLOCK; } else { return Token.RULE; } } function tokenScopeFrom(tokenType) { if (tokenType == Token.RULE) { return Token.RULE_SCOPE; } else if (tokenType == Token.NESTED_BLOCK) { return Token.NESTED_BLOCK_SCOPE; } else if (tokenType == Token.AT_RULE_BLOCK) { return Token.AT_RULE_BLOCK_SCOPE; } } function isPageMarginBox(buffer) { var serializedBuffer = buffer.join('').trim(); return PAGE_MARGIN_BOXES.indexOf(serializedBuffer) > -1 || EXTRA_PAGE_BOXES.indexOf(serializedBuffer) > -1; } function isRepeatToken(buffer) { return REPEAT_PATTERN.test(buffer.join('') + Marker.CLOSE_SQUARE_BRACKET); } module.exports = tokenize;