From 4a30b7eda6595ae7718adc5c579c2362a738591b Mon Sep 17 00:00:00 2001 From: aboyko Date: Thu, 13 Jul 2017 18:41:40 +0300 Subject: [PATCH] v 1.1.0 --- .../Versions/A/Resources/AnalyticsWindow.nib | Bin 38700 -> 38700 bytes .../Versions/A/Resources/Localizable.strings | Bin 0 -> 798 bytes .../Versions/A/Resources/RSPMainPanel.nib | Bin 22050 -> 22045 bytes .../Versions/A/SketchPlugin | Bin 365896 -> 378496 bytes .../Contents/Sketch/manifest.json | 8 +- .../Contents/Sketch/script.cocoascript | 25 +- appcast.xml | 12 + source/SketchPlugin.xcodeproj/project.pbxproj | 46 +- source/SketchPlugin/Config/Config.h | 27 +- source/SketchPlugin/Config/Config.m | 16 + source/SketchPlugin/Config/Macros.h | 12 + .../HTML/Sources/CSSAttributeSelector.m | 111 + .../HTML/Sources/CSSCombinatorSelector.m | 155 + .../HTML/Sources/CSSCompoundSelector.m | 99 + .../HTML/Sources/CSSInputStream.m | 138 + .../HTML/Sources/CSSNthExpressionParser.m | 50 + .../HTML/Sources/CSSNthExpressionSelector.m | 131 + .../HTML/Sources/CSSPseudoClassSelector.m | 46 + .../HTML/Sources/CSSPseudoFunctionSelector.m | 91 + .../SketchPlugin/HTML/Sources/CSSSelector.m | 44 + .../HTML/Sources/CSSSelectorBlock.m | 40 + .../HTML/Sources/CSSSelectorParser.m | 426 +++ .../SketchPlugin/HTML/Sources/CSSSelectors.m | 177 ++ .../Sources/CSSStructuralPseudoSelectors.m | 313 ++ .../HTML/Sources/CSSTypeSelector.m | 50 + .../HTML/Sources/HTMLCharacterData.m | 114 + .../HTML/Sources/HTMLCharacterToken.m | 101 + .../SketchPlugin/HTML/Sources/HTMLComment.m | 38 + .../HTML/Sources/HTMLCommentToken.m | 59 + .../HTML/Sources/HTMLDOCTYPEToken.m | 84 + .../HTML/Sources/HTMLDOMTokenList.m | 109 + .../SketchPlugin/HTML/Sources/HTMLDOMUtils.m | 32 + .../SketchPlugin/HTML/Sources/HTMLDocument.m | 243 ++ .../HTML/Sources/HTMLDocumentFragment.m | 46 + .../HTML/Sources/HTMLDocumentType.m | 162 + .../SketchPlugin/HTML/Sources/HTMLEOFToken.m | 37 + .../SketchPlugin/HTML/Sources/HTMLElement.m | 216 ++ .../HTML/Sources/HTMLInputStreamReader.m | 278 ++ .../HTML/Sources/HTMLKit-Info.plist | 30 + .../HTML/Sources/HTMLKitDOMExceptions.m | 20 + .../HTMLListOfActiveFormattingElements.m | 158 + source/SketchPlugin/HTML/Sources/HTMLMarker.m | 23 + source/SketchPlugin/HTML/Sources/HTMLNode.m | 776 +++++ .../HTML/Sources/HTMLNodeFilter.m | 86 + .../HTML/Sources/HTMLNodeIterator.m | 153 + .../HTML/Sources/HTMLNodeTraversal.m | 76 + .../HTML/Sources/HTMLOrderedDictionary.m | 157 + .../HTML/Sources/HTMLParseErrorToken.m | 38 + source/SketchPlugin/HTML/Sources/HTMLParser.m | 2610 +++++++++++++++++ source/SketchPlugin/HTML/Sources/HTMLRange.m | 767 +++++ .../HTML/Sources/HTMLStackOfOpenElements.m | 374 +++ .../SketchPlugin/HTML/Sources/HTMLTagToken.m | 128 + .../SketchPlugin/HTML/Sources/HTMLTemplate.m | 41 + source/SketchPlugin/HTML/Sources/HTMLText.m | 94 + source/SketchPlugin/HTML/Sources/HTMLToken.m | 91 + .../SketchPlugin/HTML/Sources/HTMLTokenizer.m | 2453 ++++++++++++++++ .../HTML/Sources/HTMLTokenizerEntities.m | 2283 ++++++++++++++ .../HTML/Sources/HTMLTreeWalker.m | 236 ++ .../HTML/Sources/NSCharacterSet+HTMLKit.m | 43 + .../HTML/Sources/NSString+HTMLKit.m | 61 + .../Sources/include/CSSAttributeSelector.h | 72 + .../HTML/Sources/include/CSSCodePoints.h | 144 + .../Sources/include/CSSCombinatorSelector.h | 52 + .../Sources/include/CSSCompoundSelector.h | 43 + .../HTML/Sources/include/CSSInputStream.h | 62 + .../Sources/include/CSSNthExpressionParser.h | 31 + .../include/CSSNthExpressionSelector.h | 72 + .../Sources/include/CSSPseudoClassSelector.h | 34 + .../include/CSSPseudoFunctionSelector.h | 38 + .../HTML/Sources/include/CSSSelector.h | 90 + .../HTML/Sources/include/CSSSelectorBlock.h | 31 + .../HTML/Sources/include/CSSSelectorParser.h | 36 + .../HTML/Sources/include/CSSSelectors.h | 277 ++ .../include/CSSStructuralPseudoSelectors.h | 147 + .../HTML/Sources/include/CSSTypeSelector.h | 41 + .../include/HTMLCharacterData+Private.h | 28 + .../HTML/Sources/include/HTMLCharacterData.h | 32 + .../HTML/Sources/include/HTMLCharacterToken.h | 81 + .../HTML/Sources/include/HTMLComment.h | 28 + .../HTML/Sources/include/HTMLCommentToken.h | 39 + .../HTML/Sources/include/HTMLDOCTYPEToken.h | 62 + .../HTML/Sources/include/HTMLDOM.h | 26 + .../HTML/Sources/include/HTMLDOMTokenList.h | 108 + .../HTML/Sources/include/HTMLDOMUtils.h | 15 + .../Sources/include/HTMLDocument+Private.h | 99 + .../HTML/Sources/include/HTMLDocument.h | 98 + .../Sources/include/HTMLDocumentFragment.h | 31 + .../HTML/Sources/include/HTMLDocumentType.h | 64 + .../HTML/Sources/include/HTMLEOFToken.h | 23 + .../HTML/Sources/include/HTMLElement.h | 123 + .../Sources/include/HTMLElementAdjustment.h | 170 ++ .../HTML/Sources/include/HTMLElementTypes.h | 54 + .../Sources/include/HTMLInputStreamReader.h | 167 ++ .../HTML/Sources/include/HTMLKit.h | 27 + .../HTML/Sources/include/HTMLKit.modulemap | 38 + .../Sources/include/HTMLKitDOMExceptions.h | 21 + .../HTML/Sources/include/HTMLKitErrorDomain.h | 23 + .../HTMLListOfActiveFormattingElements.h | 139 + .../HTML/Sources/include/HTMLMarker.h | 27 + .../HTML/Sources/include/HTMLNamespaces.h | 23 + .../HTML/Sources/include/HTMLNode+Private.h | 54 + .../HTML/Sources/include/HTMLNode.h | 457 +++ .../HTML/Sources/include/HTMLNodeFilter.h | 98 + .../include/HTMLNodeIterator+Private.h | 28 + .../HTML/Sources/include/HTMLNodeIterator.h | 95 + .../HTML/Sources/include/HTMLNodeTraversal.h | 21 + .../Sources/include/HTMLOrderedDictionary.h | 90 + .../Sources/include/HTMLParseErrorToken.h | 36 + .../HTML/Sources/include/HTMLParser+Private.h | 23 + .../HTML/Sources/include/HTMLParser.h | 74 + .../include/HTMLParserInsertionModes.h | 43 + .../HTML/Sources/include/HTMLQuirksMode.h | 93 + .../HTML/Sources/include/HTMLRange+Private.h | 61 + .../HTML/Sources/include/HTMLRange.h | 265 ++ .../Sources/include/HTMLStackOfOpenElements.h | 213 ++ .../HTML/Sources/include/HTMLTagToken.h | 69 + .../HTML/Sources/include/HTMLTemplate.h | 30 + .../HTML/Sources/include/HTMLText.h | 37 + .../HTML/Sources/include/HTMLToken.h | 112 + .../HTML/Sources/include/HTMLTokenizer.h | 50 + .../Sources/include/HTMLTokenizerCharacters.h | 181 ++ .../Sources/include/HTMLTokenizerEntities.h | 32 + .../Sources/include/HTMLTokenizerStates.h | 88 + .../HTML/Sources/include/HTMLTokens.h | 19 + .../HTML/Sources/include/HTMLTreeWalker.h | 116 + .../Sources/include/NSCharacterSet+HTMLKit.h | 36 + .../HTML/Sources/include/NSString+HTMLKit.h | 53 + source/SketchPlugin/Localizable.strings | 6 + source/SketchPlugin/Model/RSPItem.h | 13 +- source/SketchPlugin/RSPMain.h | 13 +- source/SketchPlugin/RSPMain.m | 94 +- .../SketchPlugin/Services/RSPBehanceService.h | 15 +- .../SketchPlugin/Services/RSPBehanceService.m | 87 +- .../SketchPlugin/Services/RSPItemsSearching.h | 36 + source/SketchPlugin/Services/RSPLogger.h | 1 + source/SketchPlugin/Services/RSPLogger.m | 29 +- .../Services/RSPSearchItemsService.h | 39 + .../Services/RSPSearchItemsService.m | 112 + .../SketchPlugin/Services/RSPSketchService.h | 4 + .../SketchPlugin/Services/RSPSketchService.m | 86 +- .../Views/CollectionViewDataSource.h | 8 +- .../Views/CollectionViewDataSource.m | 14 +- .../Views/PhotoCollectionViewItem.m | 3 + source/SketchPlugin/Views/RSPButton.m | 19 +- source/SketchPlugin/Views/RSPMainPanel.h | 21 +- source/SketchPlugin/Views/RSPMainPanel.m | 28 +- source/SketchPlugin/Views/RSPMainPanel.xib | 4 +- .../Views/RSPMainPanelViewModel.h | 5 + .../Views/RSPMainPanelViewModel.m | 12 +- 149 files changed, 19843 insertions(+), 230 deletions(-) create mode 100644 ReinventlyMoodboards.sketchplugin/Contents/Sketch/SketchPlugin.framework/Versions/A/Resources/Localizable.strings create mode 100644 source/SketchPlugin/Config/Macros.h create mode 100755 source/SketchPlugin/HTML/Sources/CSSAttributeSelector.m create mode 100755 source/SketchPlugin/HTML/Sources/CSSCombinatorSelector.m create mode 100755 source/SketchPlugin/HTML/Sources/CSSCompoundSelector.m create mode 100755 source/SketchPlugin/HTML/Sources/CSSInputStream.m create mode 100755 source/SketchPlugin/HTML/Sources/CSSNthExpressionParser.m create mode 100755 source/SketchPlugin/HTML/Sources/CSSNthExpressionSelector.m create mode 100755 source/SketchPlugin/HTML/Sources/CSSPseudoClassSelector.m create mode 100755 source/SketchPlugin/HTML/Sources/CSSPseudoFunctionSelector.m create mode 100755 source/SketchPlugin/HTML/Sources/CSSSelector.m create mode 100755 source/SketchPlugin/HTML/Sources/CSSSelectorBlock.m create mode 100755 source/SketchPlugin/HTML/Sources/CSSSelectorParser.m create mode 100755 source/SketchPlugin/HTML/Sources/CSSSelectors.m create mode 100755 source/SketchPlugin/HTML/Sources/CSSStructuralPseudoSelectors.m create mode 100755 source/SketchPlugin/HTML/Sources/CSSTypeSelector.m create mode 100755 source/SketchPlugin/HTML/Sources/HTMLCharacterData.m create mode 100755 source/SketchPlugin/HTML/Sources/HTMLCharacterToken.m create mode 100755 source/SketchPlugin/HTML/Sources/HTMLComment.m create mode 100755 source/SketchPlugin/HTML/Sources/HTMLCommentToken.m create mode 100755 source/SketchPlugin/HTML/Sources/HTMLDOCTYPEToken.m create mode 100755 source/SketchPlugin/HTML/Sources/HTMLDOMTokenList.m create mode 100755 source/SketchPlugin/HTML/Sources/HTMLDOMUtils.m create mode 100755 source/SketchPlugin/HTML/Sources/HTMLDocument.m create mode 100755 source/SketchPlugin/HTML/Sources/HTMLDocumentFragment.m create mode 100755 source/SketchPlugin/HTML/Sources/HTMLDocumentType.m create mode 100755 source/SketchPlugin/HTML/Sources/HTMLEOFToken.m create mode 100755 source/SketchPlugin/HTML/Sources/HTMLElement.m create mode 100755 source/SketchPlugin/HTML/Sources/HTMLInputStreamReader.m create mode 100755 source/SketchPlugin/HTML/Sources/HTMLKit-Info.plist create mode 100755 source/SketchPlugin/HTML/Sources/HTMLKitDOMExceptions.m create mode 100755 source/SketchPlugin/HTML/Sources/HTMLListOfActiveFormattingElements.m create mode 100755 source/SketchPlugin/HTML/Sources/HTMLMarker.m create mode 100755 source/SketchPlugin/HTML/Sources/HTMLNode.m create mode 100755 source/SketchPlugin/HTML/Sources/HTMLNodeFilter.m create mode 100755 source/SketchPlugin/HTML/Sources/HTMLNodeIterator.m create mode 100755 source/SketchPlugin/HTML/Sources/HTMLNodeTraversal.m create mode 100755 source/SketchPlugin/HTML/Sources/HTMLOrderedDictionary.m create mode 100755 source/SketchPlugin/HTML/Sources/HTMLParseErrorToken.m create mode 100755 source/SketchPlugin/HTML/Sources/HTMLParser.m create mode 100755 source/SketchPlugin/HTML/Sources/HTMLRange.m create mode 100755 source/SketchPlugin/HTML/Sources/HTMLStackOfOpenElements.m create mode 100755 source/SketchPlugin/HTML/Sources/HTMLTagToken.m create mode 100755 source/SketchPlugin/HTML/Sources/HTMLTemplate.m create mode 100755 source/SketchPlugin/HTML/Sources/HTMLText.m create mode 100755 source/SketchPlugin/HTML/Sources/HTMLToken.m create mode 100755 source/SketchPlugin/HTML/Sources/HTMLTokenizer.m create mode 100755 source/SketchPlugin/HTML/Sources/HTMLTokenizerEntities.m create mode 100755 source/SketchPlugin/HTML/Sources/HTMLTreeWalker.m create mode 100755 source/SketchPlugin/HTML/Sources/NSCharacterSet+HTMLKit.m create mode 100755 source/SketchPlugin/HTML/Sources/NSString+HTMLKit.m create mode 100755 source/SketchPlugin/HTML/Sources/include/CSSAttributeSelector.h create mode 100755 source/SketchPlugin/HTML/Sources/include/CSSCodePoints.h create mode 100755 source/SketchPlugin/HTML/Sources/include/CSSCombinatorSelector.h create mode 100755 source/SketchPlugin/HTML/Sources/include/CSSCompoundSelector.h create mode 100755 source/SketchPlugin/HTML/Sources/include/CSSInputStream.h create mode 100755 source/SketchPlugin/HTML/Sources/include/CSSNthExpressionParser.h create mode 100755 source/SketchPlugin/HTML/Sources/include/CSSNthExpressionSelector.h create mode 100755 source/SketchPlugin/HTML/Sources/include/CSSPseudoClassSelector.h create mode 100755 source/SketchPlugin/HTML/Sources/include/CSSPseudoFunctionSelector.h create mode 100755 source/SketchPlugin/HTML/Sources/include/CSSSelector.h create mode 100755 source/SketchPlugin/HTML/Sources/include/CSSSelectorBlock.h create mode 100755 source/SketchPlugin/HTML/Sources/include/CSSSelectorParser.h create mode 100755 source/SketchPlugin/HTML/Sources/include/CSSSelectors.h create mode 100755 source/SketchPlugin/HTML/Sources/include/CSSStructuralPseudoSelectors.h create mode 100755 source/SketchPlugin/HTML/Sources/include/CSSTypeSelector.h create mode 100755 source/SketchPlugin/HTML/Sources/include/HTMLCharacterData+Private.h create mode 100755 source/SketchPlugin/HTML/Sources/include/HTMLCharacterData.h create mode 100755 source/SketchPlugin/HTML/Sources/include/HTMLCharacterToken.h create mode 100755 source/SketchPlugin/HTML/Sources/include/HTMLComment.h create mode 100755 source/SketchPlugin/HTML/Sources/include/HTMLCommentToken.h create mode 100755 source/SketchPlugin/HTML/Sources/include/HTMLDOCTYPEToken.h create mode 100755 source/SketchPlugin/HTML/Sources/include/HTMLDOM.h create mode 100755 source/SketchPlugin/HTML/Sources/include/HTMLDOMTokenList.h create mode 100755 source/SketchPlugin/HTML/Sources/include/HTMLDOMUtils.h create mode 100755 source/SketchPlugin/HTML/Sources/include/HTMLDocument+Private.h create mode 100755 source/SketchPlugin/HTML/Sources/include/HTMLDocument.h create mode 100755 source/SketchPlugin/HTML/Sources/include/HTMLDocumentFragment.h create mode 100755 source/SketchPlugin/HTML/Sources/include/HTMLDocumentType.h create mode 100755 source/SketchPlugin/HTML/Sources/include/HTMLEOFToken.h create mode 100755 source/SketchPlugin/HTML/Sources/include/HTMLElement.h create mode 100755 source/SketchPlugin/HTML/Sources/include/HTMLElementAdjustment.h create mode 100755 source/SketchPlugin/HTML/Sources/include/HTMLElementTypes.h create mode 100755 source/SketchPlugin/HTML/Sources/include/HTMLInputStreamReader.h create mode 100755 source/SketchPlugin/HTML/Sources/include/HTMLKit.h create mode 100755 source/SketchPlugin/HTML/Sources/include/HTMLKit.modulemap create mode 100755 source/SketchPlugin/HTML/Sources/include/HTMLKitDOMExceptions.h create mode 100755 source/SketchPlugin/HTML/Sources/include/HTMLKitErrorDomain.h create mode 100755 source/SketchPlugin/HTML/Sources/include/HTMLListOfActiveFormattingElements.h create mode 100755 source/SketchPlugin/HTML/Sources/include/HTMLMarker.h create mode 100755 source/SketchPlugin/HTML/Sources/include/HTMLNamespaces.h create mode 100755 source/SketchPlugin/HTML/Sources/include/HTMLNode+Private.h create mode 100755 source/SketchPlugin/HTML/Sources/include/HTMLNode.h create mode 100755 source/SketchPlugin/HTML/Sources/include/HTMLNodeFilter.h create mode 100755 source/SketchPlugin/HTML/Sources/include/HTMLNodeIterator+Private.h create mode 100755 source/SketchPlugin/HTML/Sources/include/HTMLNodeIterator.h create mode 100755 source/SketchPlugin/HTML/Sources/include/HTMLNodeTraversal.h create mode 100755 source/SketchPlugin/HTML/Sources/include/HTMLOrderedDictionary.h create mode 100755 source/SketchPlugin/HTML/Sources/include/HTMLParseErrorToken.h create mode 100755 source/SketchPlugin/HTML/Sources/include/HTMLParser+Private.h create mode 100755 source/SketchPlugin/HTML/Sources/include/HTMLParser.h create mode 100755 source/SketchPlugin/HTML/Sources/include/HTMLParserInsertionModes.h create mode 100755 source/SketchPlugin/HTML/Sources/include/HTMLQuirksMode.h create mode 100755 source/SketchPlugin/HTML/Sources/include/HTMLRange+Private.h create mode 100755 source/SketchPlugin/HTML/Sources/include/HTMLRange.h create mode 100755 source/SketchPlugin/HTML/Sources/include/HTMLStackOfOpenElements.h create mode 100755 source/SketchPlugin/HTML/Sources/include/HTMLTagToken.h create mode 100755 source/SketchPlugin/HTML/Sources/include/HTMLTemplate.h create mode 100755 source/SketchPlugin/HTML/Sources/include/HTMLText.h create mode 100755 source/SketchPlugin/HTML/Sources/include/HTMLToken.h create mode 100755 source/SketchPlugin/HTML/Sources/include/HTMLTokenizer.h create mode 100755 source/SketchPlugin/HTML/Sources/include/HTMLTokenizerCharacters.h create mode 100755 source/SketchPlugin/HTML/Sources/include/HTMLTokenizerEntities.h create mode 100755 source/SketchPlugin/HTML/Sources/include/HTMLTokenizerStates.h create mode 100755 source/SketchPlugin/HTML/Sources/include/HTMLTokens.h create mode 100755 source/SketchPlugin/HTML/Sources/include/HTMLTreeWalker.h create mode 100755 source/SketchPlugin/HTML/Sources/include/NSCharacterSet+HTMLKit.h create mode 100755 source/SketchPlugin/HTML/Sources/include/NSString+HTMLKit.h create mode 100644 source/SketchPlugin/Localizable.strings create mode 100644 source/SketchPlugin/Services/RSPItemsSearching.h create mode 100644 source/SketchPlugin/Services/RSPSearchItemsService.h create mode 100644 source/SketchPlugin/Services/RSPSearchItemsService.m diff --git a/ReinventlyMoodboards.sketchplugin/Contents/Sketch/SketchPlugin.framework/Versions/A/Resources/AnalyticsWindow.nib b/ReinventlyMoodboards.sketchplugin/Contents/Sketch/SketchPlugin.framework/Versions/A/Resources/AnalyticsWindow.nib index c8edfc346b68355f76892cb3006c00b956de86cb..39c2ab79137fa2a6b400ce2277c98d35541af876 100644 GIT binary patch delta 640 zcmZ9J-D{Fz7{>3{*ZJJi6u&0w3e+`QB~8cLqNYiC&_J4wW^4(xQhzP8Mjyf>td3Eie`}zZ}>-W1eSyd*hdRVlx zkMJ3aP^Q}O4k^zU`g%0f=NzH=(XYlloPYx`0IMQ-B{VnYpx)qis!i%h=QGp!F$<-G zMpej53&AxC`P=AcvYqQY>@uC1GST3Kl?`DOhw&Kgj@kKH&$2}BgjX&?g~t-NWv=!9 zP>C`NuT7#v;h=?HxZLz7(CVmcv=^WN6(uRRp+%e0rnb;}6 zfPk$k5k+cIlhRVFyTGRp4$0<|Y?`InJiEspvn95|zOy>*^K5IogjaADui`bli5#Ec zQ+$StTzB}c#6H0n;jKiA;Z8aK4|nEBi%ec0(gWvx2`KIg=oHIJb<=PvGPp^egWP}Q zd_Ce~$MHCh;yBLW1x(^ayo?#%AInO@fLgKJaIoBPAS`F&!mWB-F(+C#={9h*z}>i7tzXSIVLS zA)YH0iio-hSsw?wFv?~@$gH7m!?w|o=q^F(vVxv>TOf4)oSWz3|D50NETnY{Y2CAe zon_$@Y`|x%*jwcSl*NPI9wYWTqc|V4;m)}ik{A8qLF@`z(37Iu<;GWGi&BLul(k?o zZWCtrK0W>(ZD&z_mdE&I?2OpO1<#r!uR;!A4tL09_#h$^bFxsp+d45H+apn>-;{+c z%xF>Fin>=-@NV3K1F1hE+U=LA(TbP) zo;Kngrv;Z>O}O8;+?<0X9D@LXZ9q;7PPu~CB25D{FKSWUCVhQn#^=PJu4diP4jSE? z;?mG*xh2UivKtK9eJ0ontFSMu%C^{7_MJ=I$bCG(Pv8^(A;VMtoD0!({ISG{6bewn z#o<-9EpQ^yyZ7zzsIVK@KHX-6a2b3KfWlDZ?71cxV_u*FU(jG!vX)n}j2zTYyX zKl)`F$lN(i6_m@XQmHF%%Nta~tU;9uP)hDViDocCD=oRb8j#a4Rwkec=X1{ZjmoF$ zM19o|Hx8$Pew}tWJn(bs?AWwRqJ>7_dEB^<>c%v&mq){sWeOFj NCA)c<^#7cX^#DThdFcQE literal 0 HcmV?d00001 diff --git a/ReinventlyMoodboards.sketchplugin/Contents/Sketch/SketchPlugin.framework/Versions/A/Resources/RSPMainPanel.nib b/ReinventlyMoodboards.sketchplugin/Contents/Sketch/SketchPlugin.framework/Versions/A/Resources/RSPMainPanel.nib index 294d42eedd63e6a64701277028d6b3978562476b..18c13360532fe21da517ae323f1fcc70153075b7 100644 GIT binary patch delta 4042 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 BQI`M! delta 4026 zcmW;31$-0d!vJ7lK+-rQ*SItnzj!XWYc9!qdGlV8QglcM#fl6Hlwkt~1S_zO@n<+4 zKGrd$=!$p6-DMp*+=~q;vhMr+zUNuGzW%E9^*7yWtjuiRcfgQQeTR$~G{%%yT-*m1 z7xx<0XZY6Fjjcg`@4`OWg%R4n)s#J1oUY|H;>ma(9?fgX>(1-X8_Ao*o5CyMP3L{f zo5`ESo6TFyTg@xut>LZZt>=~VHu3K9p7Y-EReU4g#gFjw`F;8Q`Csw}@{9O``9t_a z`NR1m`J?!w`D6Lx_$B-~{CWHZ{6+jy{u2H&{tEscel`C^hBzac(L19kV{|$rol%mp zEaTUV^%>+yL!=aWL`hLfghV-_W}+6NTv48=ji{}tz36jMCs7ws zZ&8t`L^Mk@S2SO=P_$T7A=)9@DcUbOD7q!OBf2YkCVDRVAP$L}i#v%2i6@AE6fYNV z5N{VB6IY9`h;ND?iXV%gieHLfi{FUfiQkJqivN|=lQc+6K9eXUT8TwMNJt4K$(AsZ z=8|@jE|LPtK*=D<5Xn$US~62IOEOzBN3vS-i=fr!+DzJ9 z+ESV;&6Bo~wv)D(7D;DI%cQ%choxtv=cE^;m!yA6|B_ynUYFjMzLtKH*2(J0Fj+vB zBTILX<;(iXzL8Cnt(C2pmCH8C_R0>(PRY*5&dDywuF3AoMRJK;DYweq@{l|xZy|3j z?<(&jA0+=uK0#h0pDv#*UnO5B-zKk;pODweKgd7H>lF1A4HOL(jTL-FhC--ls?aKI z3Wvg_a4WnDzapp@ub87)t=OX2omL!ETv9y48enS7ig_^#%f=EIi$M%wIaqV7C615K*+@n0Fe59(c5~(CAxe8M$Rce(@6;Q=g2^Fi#Rei4Nrs|~{q8h3i zrW&i7uKHH>y=tCnvucOxlB!1aPAyd{)NXZ19a95!Qk_z_Rd-PrsC%e;sRydZtEZ*a zi`A>to7FqiXVlf|JL;zzy~d`YHAzheO-D^rdacp<_Arw z=4Va0W~b({=8fi^=Dp^F=98vQTTk0S+fdtB%hy`8acz#ag*I24r|qYmrCp~zs(r81 z>x{ZA9j;?_Ep)wg19X#hi*)Igx^mri-3#3--D}+&-CJF)?t|`=u1@!#zP|o5eIq?j zZ_+#UUcFx*)RX#l`VRWf^#%GK`f>UR`m}zA{yY62`lI^e`jh(8`m_4;`iuI@`Um<) z`X~BY{RjOgeVw6+0UA;U&X8khZfI#}WoT_^V`yjSU??(-GAv9RmKc^9Rv1m1-L zat?A1aSnBkajtT%cK+i0)%lxqi}Ql>lJl~&+L^xM;<=i-6fVrAbg5ltSFS71)!Nn8 z)!xwbZrTwbHfPRp#30+T_~e+UokDZ$L;ZYI(zaxUwFECx_kP2W_#v%=6dFP7J8~Y`#lFdhdf6-XFV@HuRU)( zZ#}i14_>WT?=^VSCa>8`c!ShYw2s{YvXI@``lOH>*?$5>*HJJ+u+;c+vcnA?ey*T z?e$gq_W6$cPWsOH&igLj0&4=VZ1GfX| zCxL&04T8d;Iv5VN40Z^13UUiAUj42})X49*Y!8eAW&489Kj7it=EhuVe;LlZ+k zgyx6Vh4zR34E+_l8oCy`5&AoHJMPd~KW>7y;rPNYt1@$vkMy;WaQ75RA z)M@H0^^$r`{X@N_YH2mCrFFD{Hql8sMI$*GPz7QraRMU9InXOC(vy-{R z+-Dv#kC|u83+7#n9}~nxF=?!6EGrg_k+DcDI~I#|j(r&$7#kETjtz^=j4h2VkFAWY zj{O>|ik*vHh+T?R$F9a6$3DjXjr|vI5N{NhrQ=y~JZ_CU;zT?iZyj$NZy)a%?-K77 z9~K`G9~B=H9~WN`Umo8cuZ*9H--!Pmza769e;BVzNE1yG@i#yy+I$) z4}1v*fy3CWEP98khmT12e%aFdNJP^S}bI2$X^)U>R5e zR)N)^46Ffb!Fo^*Hi0c*8>j#~z%H-{RDvq79~=aS!BKDmoCfE>MerxM0g88g?zao-JoLv0K<}Yz4c6-No)Y`KYNfp%pPTrvnScp z>{<3ady&1&RwYwQj7Z}v8Om%YzEWFNCn*&6l*`-=UCeaqIeAJ|W9U9w)XL9$`8 zagv`DBt=O{QkHC*Oe>O^NmWvl)Fll`Q_`HYByCAY(v@^4y-9yEm?V>tB!CTJW0(Pj zPz58RVG44v8EgS_VIFJ) z+rbX7BkT|3#;G(co-goC*c`*9$tdg@G86k zZ^1k8X=-z7YpNo(Gqor6M{0lSP%3>ibs}{-buM)=^=Ilz>U!$$)ScA*)T7kX)brG< z)SFao>SL-7)kh5x4+)SM$&egnA~n(>BQhf^av%bEQ2>#MLQxb)EJ~pq)B?3aZBTpE z5p_XbQFqh}^+Em7Kr|Q)MZ?i3GzN`BX*3y?q|prYJ(`7nMDx%>REn0O73gPFhJHiq z(MGfd{f>5^-KY}nLkH0jbR3;RXVC?83H^!wLRZmsbQ9e|chEib06jua&@=QLy+p6k z8}tsnM<3C@=s&JL_ZioS<8c|BkP~xKt_dgSFiy#-IW4E>(ncz z;6hxOqquC2;o=&x}$25?2( zV6K?^iW|<2TkrqP{j8I^{)hhq Ds1i|1 diff --git a/ReinventlyMoodboards.sketchplugin/Contents/Sketch/SketchPlugin.framework/Versions/A/SketchPlugin b/ReinventlyMoodboards.sketchplugin/Contents/Sketch/SketchPlugin.framework/Versions/A/SketchPlugin index 1738c4637c4bae70a7affe81cd96e78bf9ef246f..c2a11543609ff507f4ec1abbdf8ce25b2ec5d171 100755 GIT binary patch literal 378496 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%0D3<~F&cHt}E{U~&+i6z3olv~wJ46^r-Y}zm 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
<p^!$i|9GVB z2@Q_APFq9addc6)(hc8{ZB#dY#&l<3{a}5;=(YT->dnWe1lssFxu=Gd^%I5`)I}Dm zfWZZ0zal+;zm<0Sh6x21g65Qe0sD~o%jhp)7``e1>n3Zg)!pObub~O)u7%N%(1>$#{D6xngq-mo~x`=N<+Ul!9ke1uC78lzthN3{If?H!txtkiD zzN#$2p%He{dGTu~&=!W#Gpw-stNJXQa&7@OQ0qNaoarE+8;z&~JXU3nR67vynxy?C z3M`Z7@RL;K4#th`hWgyVVIKRZdhRde1{>a(g%y5rtGMBOcsrEJoS~bIT4}y?x4ABM zjbW74d1R6S4?XAv{?Knko9MC0$5`Rj~o8p9HweB$zcXBfAaMP zjzI&?SR*;0)~77ov*Hv;;9zb$#3#xo^M6|^%#3+fLe6A9u*ip(vR}`x^@?9$tx(v@ z%E1QNo6>ExE!x`Ak=dNHb4c=!$BU{BMwQ!V760I7RbJz*J?On5mFgx$nZ>P7DS--o ze~h)`&_^{sus5Nc5mJqSd_HJ7*ufAtKM?y)tQ9To2GSh6h7cLBizM0#*@@3_*h_|p zuwc`1mCI!P)j#h+hIYK$SkSIPnXa(sjWTS1Zz<=r=kpb;48}*8K*u_Z1z!9^()vA( zy`rv99oB=*=!`#O0DZnWQWUY9R+{0@gN^p!l*41v&O9LeeL8vfB zK%NmG@R83o`hwFEhCst}52N4-zS&^?YqG!1 zAmOs7qr0eJD$xfFl7YnS{;u(KvGYdVQg=5F$#NLKmCiSj_rMvsLDO1GzdE! zyogIWdcVN@V@J)LhWJ;(tb@7`m24K`%s&2=e3d8roUR2cFEV+M80X)b64?;9FMqTB zB^CCy*0M)D6OZPU`vH43r$_j5EJEfY)By*K5J$x>KC-Ynw;C2v&|(a4UTlA$pg|Ov*i-bm;K-0&8y0=8 zE4nVb=-sl4M*mppgRLhv?i?1Meo4$M0+FdOcP@wL#m1WV2 zlWf~?D)q;=lWu!IN-*wR0`Zb_U$ve_p-veSFNt^g8S`wI@eioE$F?*G3NsaZk2NX3 zVg?ty66P|g^<7A<;zE)Tg`}4mzg!1NFXw{Jo+_1lr2izzDY}9#TrhJEH)DopGSs~g zjrRv28p*k)4SYQ!(RK$F;al_P-y5QOLu9wh(QFcbFSe||M9q$9K>_#v0Au!_r8^tR z9fdOZ$m=(#er}_`e_&3kKWn&u3&(Y;j-O!6mrIaGTHP++@5pbKQ0z8Qts-9$%J|)2 zY1$Wxx?m#G>C@3i6pu{31TMNYoM#`nWoP8~7mV#*h3c%r0<#d~G_s!%grm?8GCjT6 z7>q8I`0L0L8scO?e5>eeR}3IS9LW8P$ezqEzbiAlHalc6fX>cJNB1B?sSxZ55huD9ac78a3__$$P9%#y&=2z}7wF8uI$&fzd=vM(T2sz}EwW9OA*0tg!$ zn+aAr@WP48i*4w$ag%NJ;YyC4oQmzqh=3y7k4);L$>D6@iPbnG)Vl6!yM#sp@B6=F z$C0{34UGTyIuVm?Rg(J!xWM^Ol30wwt6ebX@x;o&^%d(*?sRmCGCsbx3qpALAIvA+ zh1p=Y@~&Mo(?IR(n(C(4<;kT}O;4p$OL>8hLf({5KwW7Hm~fA1BFXRZ-2-nTTjX&j zI^x&^(7`?urtPr$DswKxeghh^Q04Un2ee2;WQ6|ZMJDQ91X^74;0 z0q38|V0yxLVYRbbhmfom3Kkr=FV=Kl;YiSH=Fys(Xhmv6@Wmv#4o38Fi`FD*?ZJx1 z^%D5;sc;Xn6UPWZ27VI=L-wkd?Rq@S6_uJB6!ilZoS8eZA7Xw{Ax^c}Q$Pxnzq%)} z(iV_3wpu!RGl_`J;j57vxg|1-kN7nQ(phc#Hl}Sdg{aE-(DosAOxwILB3hUM8y3dq zZ)ITTg%Ob-tz(7@Ltf-_MI?3#R*HD%q&)<8;blSi9U^|WVr@aF2<$8f%^@OtL1;U_ z(4c)-S$DU3ET5xx)j}rqI8-0Din&eu$Di}ZNEK;=PBOpsHVfjB;N=o?UZ6c)`w)d2 zEFLwi@1_x&UpUeQ*DLK8e& zyYylo%ScW}|B9M48v*}cXOSi^?hu=LZOEDv_IdFdB_itVnX#qKeSq;ZJ`JUA=-kyZ zO5`N9_o@blaBIzP{CTnL5ztsIe(D@f_PXUMlnqDyw>+Q&Anxfp5w~KxX`bnst`=c5n9uagR@*{pL`TvQu zPOCdfodxlL;HYjgUeDT_{OIqco^gZF_Dt1iWSccjH!%OXp{YKa($4WX151kS58znO#DfU}$zm4{LuKlWh>7w)P_d@%< z$bM(o?@arhWxto%?`-@1z5QNczgODtRrdQw`<-LI*V^wq`@O+_Z?xY(+wXk)y~TcS zv)?=HcY*!hX}@>b??3E!q5a-xziP*H(S!E8*nXGT@1yp+%zj(!_X+!5VZTq=?@If9 z#(tmUw>(*RHzVZWk?EqF_J(b0P(q;x z6uLv9I~7`hN@|<0&`O1_Rj5s&D-_CSSZJH6(B2AZ?5!TCP_05^6dJG4MGBp&&~*xF zC9L{xg@!5gtU?17`dFdgD%6QFvaPp5Jr(-3LdPhi`!=eZ6#A7yS1P2rN%cJneaB3q z`bC94Q|Mm`y{}LY%%L_-m#Sk5y`WIJLMs#+uh0^OE>KAGk!t!=UfUfC>8gab8x?w8 zp+740FNJ0+v<=Fv?IMMGDb%RY5el8H&ung3caXMe}z6% z=s<*EUZf&3fCeROnNMW+}9TQqNZiTQje1 zib7KqnxN1Og-%y!o0lF+2uNsT8@YOEeyTUj%$aniVkvhh{5jgux! zs;VE5r^LMRlg2eps;jN6pO!biX-dtcag~i#8K8!|hN{Nn$DUm^u5rMGy82_Qrd5p} z*)+CcT>YdejRW%Pt0vc-TjkP+S@M9qadlI&P?elZc@3l$gLh(G{j>p%bw>{_8#*Ab zp|NhtP`|`UwG%f5%&Qzfev;8vlTFZpfDK(Yjs;cX1##hxlM0HbC;f4WI>gy)fS2Z*Y7*{uWN=;Q`)p!^-{>(|WjaBv3 zc;qj|Q#YlmzEUV@xdB1xLu%^Aozrm<)s^*C<11jt#H#wdah2n$tH?;}iP*dbOEp4^ zm6SJ0To_hgH`zV|0qCHfqCF^GThAI;?Dft;2?{Y8*91Y$~p+siEi5d?!t+I!|3I`zfT~q``_G;F9V4KA$NODg zUCGpk%Q~sHp{l-7;0=Qt%K{7y1M-lv33c_8hg3F>s~$CFJY7AMT!=5NtQ}t?h0{>w zSI6>JHRRQqW(kmyNd>mAHBm#!I1#Ltt_qK=YpNgTKJ&)aR5mo^O|CqrN|afr%qTg? z3JFEy0pJ(vS0G27nLLZtNcKdUjc)DAZO8cx1w$u|FRrevome$8s9O70%D~d&swPyy zA(5#DF~Zuz52$ULJhrO-_zA}5vP`SwHvRxrg|-_}1=a?1Y?a?;Sq(EFFTmwDZ9`dY zd*-&odM=d*>&T`lXr0NRWn3t6q2nhUJE?a3fXYn6!_S72-!)a%Sj$cbq`nGPiDC(^RPCN&JNubVoJl2rQf6N=T?D!8J`vB{4ZS63?uY&fwF_{KV_rO~Nj zN?q-E;zA0DYpk49tFBX3*-({N+09jeCeR zk}RQDG0V?@PYI>z zWC>io&)qDc-h`Duon;g7pz%gx@X)sq`I?#`RW#?|#^H6CJd&+V8?-$O|5q$OAw>Zp zRd5tBcSH#P<{PldM!lhd7^(}vD1C2I-G=JArW$|P*tA-Wb)}OgR@d;aab%+ndF@3# z7;^p(d0o*?8*ZAtJx3iho!rK@pNAhmY5Xrm4d^e&D|r|?sR3honuw4%{PeKbj$>K* za|SjuszBxsaGMTq?eIW!N$q%_5-FSi3o-4H{1inU4Y}=TYOJrUZLnEVdF8aarbdMB z_?q!9JfODfJU?V}y^}jIDba-1ux9o7A=lo%BF{T>l7u;rDVJ{xotaBQhC0O+f-A-pq-g*x)~waPpqSZRo0HHs=+8IwgB@l*^$GT-!@ch<|GTLF|VnX zNg4K@(=yOAp|Yu_(f=&QewZ||$*E`MK5^3ID)?EZ85d+hR8T)st$L1~S=j~zED8fw zNi$lH&nkLAUJfDkj&FGk9+f9nHk>28S!FfKf>gZWDVbU|u8BbxwGzOqdQFovyp-ZG z2HK=x$g~oyKpS^zCknOGD!%2-{E~^ofIMgH8bgX@OxEWyd^H|dCszR;0kraQ7y<)a zE{YDF2Eyn}x(44tAj{uyR@K+n)hm5y-DGSoqQ_SaXkrFYhN-4TtEnk=vs=(R0T6VF zvIT8w>}SGD+Xl@^Fl2%+5`$}Md>YhpW&?<6@^AzLD>HK^9C^|P&SpO;TiWQC9mF=E zf|<}kd0y4jDNK;6#v>_>u&BJMc48yuVO3*^pD=RL`OHY1kOzL3;>szN<0dsC%>a%t zd$a+d@iH%Mwjnz6Dlw-}EJm{5XTsuyHLu1M7Ggcx>NudmN^CHXLty!+y7ZfHcs~a(0Cf}y5 z6-xtDo&6~zs%C|WibVDF1l2a0&C}FT*LXULR+mUr<|k(4)>qCVb0x}Z+p0*C zi>MYci!G64eX^`3cNR^>37w=-z6Q0v^0bI1blmn`6{W4^VY#7h3Kdx+EgrVZi#BXm z!_amE5=pCEu7HVA(i8(NJk0fZfrMl5n5%>+V z7isr^f zDtkBrc3jnU&4~%r7IPXJhO?V*N|_B@L7Vrr;B zv=Z1DTr@01N6*xow%3!%a7Nbh4UN1}4Sb`M!8kP@YDo9S)y=1}pYTI%;b za%k#M-Gqw9F3JiPPCw|EBxTHcF*26l5-o~{9nwl{5b}J3Qs*cR!U|Sr;WuvfCP9(p z+kAQCsoFLe_N1&mr3uI2Cx!WrEqayqrA%x;d3s7lgDE7^KxnQ=Q&sLiU0d6TrA z6f0_IaWRl5%1ai{7-*x#+7wgX0_nTCC~QJB2`XrAoRTP@k+hT$4Jc?1oJC9ByhVfI z8(B4{F=_K~WMg%ub(m~wn$6PwttoF#CTRt{n#Pq@vK{yjuj9G8opMTj`CbqSxvJEDow5~wtCX= zn)j=@Vlsb0}ElxuBq6%}NqNm?+>p9zy_ zwjoKymIODa{OWR^I9F!z0HKjwf5S0}=?R^!+IC?JY#0_-cqf@Q7NlX6+krDR!3ngq zTR(&IYh#l?p!P?Nm%THQsaVG}(iSrHr?y#g4JETn{lk(*sx-Lp**sc0euX5rj4801 zB~|)9Ny;2Gp^i!+P{*{nv$y3H7m$)g%}qSNWk=S)HPYW-3~ozK(S;~x3G^2JOiHRK zO@gG&&@hb_@ugo+Ig_mR6{YfPV*s*46Rpsv@V+5@imgymYkeH0I$B+qEx%!YfsrdA zgV?%9TwF!@JM{}GUq`EGe({$0+$GxJO$ir`xG>r<5Bg9V0*BlT4P31IzZprk(M)z?q0M#q?<(KM!@ zx*<_R2IB?3Dp4D=0kQ+-ER~%R)rp!)>RMBovismvn5p@jX{LhVvY>|7)HI{Mu`;k= zVmm{kXDKa<%+o}3h6D{Ltk%}51&!79wDH3y2k2aYT9CUNyAoMnXMK;M#FIId)X04n z<{y@@Ex)cpR=|#F!(^rET8+*fwfQG1Wq6D6oOGZ*6Hk@>#Oy((yzp{jz&7msY0T-L z3rJawtst{=uBNo$#0ywtYw1%cWyj)K{vvf7f?Jcd*-;^(ZY!pp`llp0aiwO~-EBL@ zqv8*7X#f?{78#aCQ7RTSE?6T3gIZw&1*jP|fR-Xv&SEqXTNfmD(CiW`)yBx3RKk;J zJJAWf))e+PfhtQR)+6A{Lb6o zPtwCuO@TG;Fws<1CwaWUm1LxRrSg?U;oyM)B9l|&rQ!gVYXXhwYKM`Jpm8V-qnIs> zA`@y7wAJEDpizF9oxGlmS&fWYsU`A=$&OjAbdYUH@mP{}SQ&2zR`wf)Pc)N&pb|(T zL$jz7ku|-nv6=^Yh8-MB7!QOM!lg}``%ER4iv~M&G!AGiv)iE^jjr3~G|R~-xttA_ z#!Kql`T9v0k@HAU#z`yktv=eW?xsmj zlZ+KH9qvMnga-5b9dfB0Q)k=6n8xwdWm4CQFbT%$0mrSXpW#e2>WQDmi9{qv z-iF3_SpjI5MAajo)~uUk|1qdtNPX-X*%}n!*ON<}yWDy{%TrE&Z9QdC)jZ{(2F~Bb zFnO}l>DvbhQkUC)u6S!mPR80Oy6!|}CPyC|a8!#DX`<23G~U?ctsmZUpsZoR9~fFe zBWb+V=rhRTv`^P19GRLoO|9nhGd^=sAdHnJ8gAO7V$?g+h*m?SjlXhbW6P?(eC7QS z#F08{r>h#3Dm_kY@Z7MWzLBO*ytPH1%N{T#uK?v}+>Qk&)DCNHl_LsC_PBJ4d0Rmg z2xiOf)>v)Wg6*C)m4Z{bq#qlWlxieHi!-6HlC2c1T-Xv*0?mRN0%c_@l3$u6U%fVuBl0|tn9(^sMs`v ztS#e>e4A0ba>&)Wtd0tTY;)wO5o~zDYc2MIEYZR)`+ly@ltVvE z2MxJ3Q6J~8;Wal=Y1k<-DM;OFQbwv!kA<@}N7*Bi)Kb}5@fiU!k4(ocHHaWf+w+>X zgmH3{8nHcMSz_bcLk1}UCE)iv^}saS_d8bakT>z2VV-P|k_D(P+k;rN$C9LBCH1B= zlUY@?fGXB#&UIc)8=!lQ`rPokPJ^XUczgX^xh@aL|laD`d(i%S)-Fp|a$c2X$y%kkU*x zV5^&WC{dkPQ{QYCjbw5}3*#v?m4KX-;<=SAY^tHM;bDyxMdY4$rd@^2k*%xIsbGp` zH+#rTO5`xG|ADYuFo0 zCVBOV7I)}arG%MBqXoGt#a5Lm9CPN>G*p#gKv(BTHf1wt!H9QVXj#gXv>}(YBT^j< z4@sJMGoLLuH9-nZwf5ixo~eeB;v!MPFwAb0^NSzkZh51hPNv)A4)j&rMLPtR%9ABRqOom75w?YJZS^agQq(Qy$?S;EC$pY>ED0jm$hos*t&)Xv z6ijR~lCe8@sbvJMdhFg{2F)2Q@X64pDR~UdDX5I?35z@`ZX2e76%7{UE7wgw#7n&V zMh_j+W3BBrKq^Iyx!mHYZqj0aDYdG&Eb6&8yhWG z%*U$2dOQ-MzAwv6P0VU4qQNMw^vtp`xB}{!&5lFZG&Fyt_7l#y)KXMujQC8dzRUX) z;WA^RTGw2bIxj}Oen%CUWrm0m zh07!^gp>eONmd$O&gQ^xm9Po*bmEq&7iCLpneZA0yU3DS^^x4qqt>gFsjUYNX!4p7_3m{vVc#|sHcY!+ zeix<9hy~d9I;nPYUl$}+=#=)5m;QM1ZlsAvSGW(rdc$1rk9;2*JA|0me%Z)@n%)nzSMxG@qAlYNJ`4A zS@P;A7+4NF6)k-}`sN4Zlp%X5yFsH{jCTLUZuWB16>-$ahu4wW5_Uf-kXna_U~Qi5 zNmi=uw=1rgf9>@s(tjo5I|g_Q)_iCuton*}ZW+T(m^b0wknNCiBu zLAH%$-;i4$Wq`L3c_-5D7SWi5W{+GqCeR9VBCCui3$%Jgwl{%Sk)`4JD`aS@slL^= zv4YgA%Q-sAg!7>pO!$xl%~;9V(b);Rgkd{Ld$1uDl-fv}yR`R3!vY$`Q0uJCBezAz z-esIfTUc~jL^sOeN@SEFCm#}(cA8Ahtci-BrubZb;=g&filWo*)JS{CFw8T8Jsz#I z**8qGu+HMI>5nGQh&>^+U=9kok(MTP7ne?LP@hSwNHmm59g^aDO|o|C>itmC2n!UBk~?1I<^Z4u2VND=R8 zS5e5Wv_vflNMdvtmJfU2;0RY?>-Qx=DKUGcf};QxMNoxcAfTnpAo*MdI{_XH1kM`S zj-PDBqje_RYEEtf?GWK#m$fO=1wDcS*pqODfEEJ(`={N6de`7CQ3 zBq6t^tZpisipv0krvw{M(9 z^HCZavNxcvorVZS^mY>YEb4^xwS5|#@);i;<8fMUB(nZdMPu@%GBE>9!^*-FJ~Ac0 zOhcVsSsfj|wWBJ#zbyGsi|a9;&?zhH^X$p#B3ZjFq3Co;NShYT4VR3hCPi;ykHQqu ztc__h9&D$Zu;WBhZx%Om-fhY@s@CR6D7j%&)$rgruV87f~g| zw1zhX{XQ*7Xdg-0^9cv-wXLBG@KP!0jBAGgj=H3B>QYl1hNiHHCPVZJe3W&3`Cu#v zx#igQX3v0lwTv7!N~xlFa;gXKZBC<7)nOK@p&jQonKYtU|Aufnmw#~UmSYCCY$<3t zbDOLA(iF~&^my#FXm#6epE4Fo zU#U{FH35Fa?*A85(M1DcD{`uolCbguq*P&+iViV{E*!9DFs1eec}*9}-I4Y6Q)tOe zZ?&;jBSm*&5nODxG)%@0W-MDu+3XZYdJ)zT-5Kv{uz^D7##ogEou#XwD=U0!`I5N} z(m zG}8xWreusgXh2ZtP?j2`XAfnDfrCOZvWE`LG}8~Z+Od)Y29g*?(r1vF=Ic0(q-ltB z2^U$<{)aF<+vnySvC3gKF4>;oX+tC#9K+ui>B$MEjG|xLi)XS!*`!>uBrb-YAhZ{Y zd0<{jh61UiNkT;`>Akc(1eHZ)hn&(^n^Q?eLPRnZhyfuaz?avP))(#78kAo}vc&Pz z5oavmiL*=ci;knk`@tsz6Hr*?yZNr@EWe2)*_8!Zhe3s5I*VehLY?b>8ZQ-v4oBfC zjX#iHI5KN)2W_1dEOic0nDs!7_zz?HIp^rXWZy=l7C#Zr^ z`h?w-?W4t^*uvu-1@@nzaRaqd>T-Qtlw{iji!5}s6pxrwg5f#CD$sb1w!wHGh$f(P zeMD!zJ{%iyB-wUJC}rslsKAd1bET#~I*K16Dfc4O=CN8CpLu1jIxHaJq&+iC42Ih;XFC*Suunw$N*bs zY4BldF~!cK1$CMM(}8T(g2$ga%oOP%y59nA1C=7SgTR1K3FLyfL`Yx~hAx-)iinf; z1nntKuHV9{CLufdd9sXlR^4+5y8)*+knw4%Q{6BPh>Io(f%_8tivm~~F)?%s*kFjQ z(|*I>fTa9fjH+vB=FJwmRiNh(ZZ5$QHF*WN2s5nLPzD6O2}2PV@0FNgc@sPnQ+oX=ceH%?N=6;5a#5z!e&72B-;dQ zrX;-KMc-B$%0s8?HYwJ+V_RsfHp+n@mFfQ^%sL6HiOl)_BQx2#HNVi_##n6Kwp6j8 z&TeUFNFIdd7G_%5^H7kc-4*Jg)FWsZnYY(Tiazb&Ln;m#n0*LM z_}RY)JuihxpCeMsJXmoGbvD5z4OTbBt+g!CNcf?_%=1XXhW+IhS|328?SF_JJ8BaS z_hej6WWA4?v*pwF)&ZX{x@T}v1^&RFRuh-nhv&ir{0@j_xuk0-s@2^t%}6$MIg>-9 zi}a0Y4h5t6i!C687HUKg)nWRgUW6y(TEOUgxh#1Zq%vGo6f`H!PE{p;XL|5nIwgl^ zismwvHd}s?jO8lU)9e)~*s|x_>q|*#szdDfNH48%top&J90Vx7!?A^k#U9_=qewv0 z0fjUeZqVYwZP#^ZU|otvDm<#8wV>>w)TIqQB<15NX|D3Ts1&TAsLpKqKqXJD7Y6IO z)H8MoJZZHnexcP4i?O3fYZe>iMX!KWD!A+pqSds616qsgA+1xxD$&-dk3*?Ka^^>* zj@q!^!PX~>kBo)Wqx7RoWq>ZOQEjIvfz?HkgBOW=`l~Ls{IaYGsaDJSrX=QX+DVX3 zsLCtZ96Tb}0)hr5C1w0e$u-Fau0&56k=CE=O&Bx?=XdXE@M!a9YeH(>lXBVLH}mYF zgQ<9UGlN$Y6;hJbqi`ba4E$U<{@%~g=B!dr=vsix>B_Q|YLDr4|4At9% z1_Z(bGux5Q?ZPh`V(u^r(uDc_%DzGTB%XCwQ&8!#YyU6W2NI`A%MdRa>4j5!t*JdU zQ_M9Lt-Wtv-~7Jg+r62+-HX|6+_uZieS2Fm?M9(ZKAaXy>Chxf1Qx3M7P2a4I(d;y zxe~Z|Y~RA*y}-qLQJ7A``{oO<<&ohznxt_(<%a5T@qHJS7_>?n!6?!wLp*FD9y+_sb~vrASb0JhY*~e( zhs1~*iqa^1;eJ{=l&7}Nc~LT62B972&;^Rtu;cYr5tk~F=ul^B?63Rap@{8rRQRhN zzHTWoS~LMB+!1BiC0W%KL5F4Ri#~Q6zj&IZg>a2}&6$>`wo*;SXQ1ws#wnQO8&miK=UgD&ORF!k{p|Axf}Tus@`iO6CXE8V(cB6rzgKj3Nga zZ>VXeqpGGrfSzabFH|v#p`rA2+S)X96fVvutKuALGUIX%=%3mDpn(VXA2i^A{^ppn z=DLb1GlDni<9x?V+@3JuH|g>z#D`bxj7W5n60ucLCIU1hXR)%4O=TAxaPnBv5;&{l z1GlZnNil4RyIm}`b$gJ^CpU$*)FqAZ?9GY~v+)^g*}iv_5?xYcJ6iBLdGCe}#tBn^ zl*Ex4DMNq8Y5Q%T=3gvBNd_jORy&_YFSm;jo^7H*Fs>2}&aWR*>Ex_OaW*(Rn;d%|zIc}d_d9&r;LLu5HXvST91xrm zro4!6g`RdKsM)r&Vy7L+OxdxIFt&4b1r<$xQA#>|L_3W2diY4LxS(MtcUBIT%FvgE zdaS*>zX+g(9OmVvZ@e}k`H74dRrw`p@o~-fjAPFTW zGbX(|q(Y871}+~7=RmmI;d0L1w;QXO+GXGp6aVIrcJ%RSbkvbwHED+h6uE7r9eVIa z6HCS-6FN(K#*!{P!Sy8V2=Hl1zPh9x5f*O`(DGqL+eZZ?hn+jDX&43ROk*4q=Pl?MjgiVa<<0G1F==P|ykU?E|oec?cEl2E4+ zMDdVbUf63hT5>2l!F2f?JY|GO;jD;`!8PN0k%X;x9ZXb$#tOs<3@B;*grke8l{0rt ziF*}nVqD79NXF}B3vK-v6D^jP5V#K7W5{kJB>^F_ydc_^3;4oOBSx4B!*dH#7ZO-? z?5u%@U^1AYu`g~bXy;CV&|Hb$HB8+L(809;p-6e{+#A5%5TkQw2w5zhL=dIlW!5C6 z8N#)BXFioL$x|B!+M!|9=~OtKE4Bs@v)Qi_ryUl&*BUu;v6<-CG1(MX(TYQ@y=^}( zvr=Bs;AI6`s^B-C~@C#Krqq547Z z#qurO^fqa`ukQNCbZN>zj8_8rwL{}$^K55oam3Jg0M$);cd6VI(VHQbeKfuBZSqFQ z8>jj{*{Ct}23B%1om!^Xd+696XU%qOYHxBP4A}0!M$oKXVRy4bIo9iJbiHg-pT4p`r5m! z&iFoZliOr^I4u!H!=lWM?dI7uu18zC)N|vPBLwF^9N#yqQ|7 z4*OqG-QnP%txxUw^;C=?OW-xcb}|{DhF?bv@$%d{Ob)%QXnEa+JKlYvG5qSHjg#6~ zq5{@gxsQx~$|d{}%66Q%&wQ&Muhui)r*uctH#bl?w>nAJ4^oY% zRmIV=TFdhjJ78!`(9a@K7gIBVD<&zDU2iMDoDt0}iBt zFaI8N)6i+$0r1isbrsFMD{87qXbJTPV+xv&Dw;fg{EIf%uGxe zIPK`1oI{&?H_?qBgUP8jCMxL08k!U~@l{k-C}~LV;x(CpnF9^pQ!&TZH`AWV^hBI5 zEu*eW-xH)uuZXpNa-1i2{o)1o*FNLP##!+)>R#&N z_8Jq@t2$0SPjhWuQ+#He0*&>w7-`oUX(Ue*7s^`jCV48&aJ^-d;`E8FkClEHx6Y%| z@|%4!4xeV
  • Minor update v1.1
  • + + ]]> + + + + \ No newline at end of file diff --git a/source/SketchPlugin.xcodeproj/project.pbxproj b/source/SketchPlugin.xcodeproj/project.pbxproj index a9a99aa..48d5c6e 100644 --- a/source/SketchPlugin.xcodeproj/project.pbxproj +++ b/source/SketchPlugin.xcodeproj/project.pbxproj @@ -1385,7 +1385,6 @@ 0E49C10A1E7F0CE400FCDDAE /* NSMenu-CHMenuAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 0E49BAF91E7F0CDB00FCDDAE /* NSMenu-CHMenuAdditions.h */; }; 0E49C10B1E7F0CE400FCDDAE /* NSMenu-ECLogging.h in Headers */ = {isa = PBXBuildFile; fileRef = 0E49BAFA1E7F0CDB00FCDDAE /* NSMenu-ECLogging.h */; }; 0E49C10C1E7F0CE400FCDDAE /* NSMenu-NSMenu_Blocks.h in Headers */ = {isa = PBXBuildFile; fileRef = 0E49BAFB1E7F0CDB00FCDDAE /* NSMenu-NSMenu_Blocks.h */; }; - 0E49C10D1E7F0CE400FCDDAE /* NSMenuDelegate-Protocol.h in Headers */ = {isa = PBXBuildFile; fileRef = 0E49BAFC1E7F0CDB00FCDDAE /* NSMenuDelegate-Protocol.h */; }; 0E49C10E1E7F0CE400FCDDAE /* NSMenuItem-CHMenuItemAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 0E49BAFD1E7F0CDB00FCDDAE /* NSMenuItem-CHMenuItemAdditions.h */; }; 0E49C10F1E7F0CE400FCDDAE /* NSMutableArray-NSMutableArray_CHBlocks.h in Headers */ = {isa = PBXBuildFile; fileRef = 0E49BAFE1E7F0CDB00FCDDAE /* NSMutableArray-NSMutableArray_CHBlocks.h */; }; 0E49C1101E7F0CE400FCDDAE /* NSMutableArray-NSMutableArrayAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 0E49BAFF1E7F0CDB00FCDDAE /* NSMutableArray-NSMutableArrayAdditions.h */; }; @@ -1469,7 +1468,6 @@ 0E49C15E1E7F0CE400FCDDAE /* NSTextViewDelegate-Protocol.h in Headers */ = {isa = PBXBuildFile; fileRef = 0E49BB4D1E7F0CDD00FCDDAE /* NSTextViewDelegate-Protocol.h */; }; 0E49C15F1E7F0CE400FCDDAE /* NSTimer-NSTimer_Blocks.h in Headers */ = {isa = PBXBuildFile; fileRef = 0E49BB4E1E7F0CDD00FCDDAE /* NSTimer-NSTimer_Blocks.h */; }; 0E49C1601E7F0CE400FCDDAE /* NSToolbar-CHToolbarExtensions.h in Headers */ = {isa = PBXBuildFile; fileRef = 0E49BB4F1E7F0CDD00FCDDAE /* NSToolbar-CHToolbarExtensions.h */; }; - 0E49C1611E7F0CE400FCDDAE /* NSToolbarDelegate-Protocol.h in Headers */ = {isa = PBXBuildFile; fileRef = 0E49BB501E7F0CDD00FCDDAE /* NSToolbarDelegate-Protocol.h */; }; 0E49C1621E7F0CE400FCDDAE /* NSTouchBarDelegate-Protocol.h in Headers */ = {isa = PBXBuildFile; fileRef = 0E49BB511E7F0CDD00FCDDAE /* NSTouchBarDelegate-Protocol.h */; }; 0E49C1631E7F0CE400FCDDAE /* NSTrackingArea-CHTrackingAreaExtensions.h in Headers */ = {isa = PBXBuildFile; fileRef = 0E49BB521E7F0CDD00FCDDAE /* NSTrackingArea-CHTrackingAreaExtensions.h */; }; 0E49C1641E7F0CE400FCDDAE /* NSURL-BCFoundation.h in Headers */ = {isa = PBXBuildFile; fileRef = 0E49BB531E7F0CDD00FCDDAE /* NSURL-BCFoundation.h */; }; @@ -1500,7 +1498,6 @@ 0E49C17D1E7F0CE400FCDDAE /* NSViewController-MSNormalInspector.h in Headers */ = {isa = PBXBuildFile; fileRef = 0E49BB6C1E7F0CDE00FCDDAE /* NSViewController-MSNormalInspector.h */; }; 0E49C17E1E7F0CE400FCDDAE /* NSViewControllerPresentationAnimator-Protocol.h in Headers */ = {isa = PBXBuildFile; fileRef = 0E49BB6D1E7F0CDE00FCDDAE /* NSViewControllerPresentationAnimator-Protocol.h */; }; 0E49C17F1E7F0CE400FCDDAE /* NSWindow-Chocolat.h in Headers */ = {isa = PBXBuildFile; fileRef = 0E49BB6E1E7F0CDE00FCDDAE /* NSWindow-Chocolat.h */; }; - 0E49C1801E7F0CE400FCDDAE /* NSWindowDelegate-Protocol.h in Headers */ = {isa = PBXBuildFile; fileRef = 0E49BB6F1E7F0CDE00FCDDAE /* NSWindowDelegate-Protocol.h */; }; 0E49C1811E7F0CE400FCDDAE /* NSWorkspace-CHWorkspaceAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 0E49BB701E7F0CDE00FCDDAE /* NSWorkspace-CHWorkspaceAdditions.h */; }; 0E49C1821E7F0CE400FCDDAE /* NSXMLDocument-SVGDocument.h in Headers */ = {isa = PBXBuildFile; fileRef = 0E49BB711E7F0CDE00FCDDAE /* NSXMLDocument-SVGDocument.h */; }; 0E49C1831E7F0CE400FCDDAE /* NSXMLElement-SVG.h in Headers */ = {isa = PBXBuildFile; fileRef = 0E49BB721E7F0CDE00FCDDAE /* NSXMLElement-SVG.h */; }; @@ -1631,6 +1628,9 @@ A898C3451E6DDCF200696573 /* RSPMain.m in Sources */ = {isa = PBXBuildFile; fileRef = A898C3431E6DDCF200696573 /* RSPMain.m */; }; A898C3491E6DDDDB00696573 /* RSPHelper.js in CopyFiles */ = {isa = PBXBuildFile; fileRef = A898C3461E6DDD4500696573 /* RSPHelper.js */; }; A898C34B1E6DE6E900696573 /* RSPMainPanel.xib in Resources */ = {isa = PBXBuildFile; fileRef = A898C34A1E6DE6E900696573 /* RSPMainPanel.xib */; }; + A8A5D3CB1F17609D004B2DD8 /* RSPItemsSearching.h in Headers */ = {isa = PBXBuildFile; fileRef = A8A5D3C81F17609D004B2DD8 /* RSPItemsSearching.h */; }; + A8A5D3CC1F17609D004B2DD8 /* RSPSearchItemsService.h in Headers */ = {isa = PBXBuildFile; fileRef = A8A5D3C91F17609D004B2DD8 /* RSPSearchItemsService.h */; }; + A8A5D3CD1F17609D004B2DD8 /* RSPSearchItemsService.m in Sources */ = {isa = PBXBuildFile; fileRef = A8A5D3CA1F17609D004B2DD8 /* RSPSearchItemsService.m */; }; A8B390601EF9509500201623 /* AnalyticsWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = A8B390551EF9509500201623 /* AnalyticsWindow.xib */; }; A8B390611EF9509500201623 /* GoogleAnalyticsTracker.h in Headers */ = {isa = PBXBuildFile; fileRef = A8B390561EF9509500201623 /* GoogleAnalyticsTracker.h */; }; A8B390621EF9509500201623 /* Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = A8B390571EF9509500201623 /* Info.plist */; }; @@ -1641,13 +1641,14 @@ A8B390671EF9509500201623 /* MPAnalyticsParamBuilder.h in Headers */ = {isa = PBXBuildFile; fileRef = A8B3905C1EF9509500201623 /* MPAnalyticsParamBuilder.h */; }; A8B390681EF9509500201623 /* MPAnalyticsParamBuilder.m in Sources */ = {isa = PBXBuildFile; fileRef = A8B3905D1EF9509500201623 /* MPAnalyticsParamBuilder.m */; }; A8B390691EF9509500201623 /* MPGoogleAnalyticsTracker.h in Headers */ = {isa = PBXBuildFile; fileRef = A8B3905E1EF9509500201623 /* MPGoogleAnalyticsTracker.h */; }; - A8B3906A1EF9509500201623 /* MPGoogleAnalyticsTracker.m in Sources */ = {isa = PBXBuildFile; fileRef = A8B3905F1EF9509500201623 /* MPGoogleAnalyticsTracker.m */; }; + A8B3906A1EF9509500201623 /* MPGoogleAnalyticsTracker.m in Sources */ = {isa = PBXBuildFile; fileRef = A8B3905F1EF9509500201623 /* MPGoogleAnalyticsTracker.m */; settings = {COMPILER_FLAGS = "-w"; }; }; A8B3906E1EF9639000201623 /* RSPItem.h in Headers */ = {isa = PBXBuildFile; fileRef = A8B3906C1EF9639000201623 /* RSPItem.h */; }; A8B3906F1EF9639000201623 /* RSPItem.m in Sources */ = {isa = PBXBuildFile; fileRef = A8B3906D1EF9639000201623 /* RSPItem.m */; }; AB1F5172AC711D07F1330A63 /* RSPSketchService.h in Headers */ = {isa = PBXBuildFile; fileRef = AB1F59B028621B306E86B41B /* RSPSketchService.h */; }; AB1F55711BE6FA33B290EDD9 /* RSPLogger.h in Headers */ = {isa = PBXBuildFile; fileRef = AB1F5A44B2B11DF74D2F6B5D /* RSPLogger.h */; }; AB1F56E07198F115DA5D7E7B /* RSPBehanceService.m in Sources */ = {isa = PBXBuildFile; fileRef = AB1F52B5C95939C09463B611 /* RSPBehanceService.m */; }; AB1F59361655AF9F35360E2E /* RSPBehanceService.h in Headers */ = {isa = PBXBuildFile; fileRef = AB1F599110FB81A3142425F4 /* RSPBehanceService.h */; }; + AB1F59B21ABC5D245827E668 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = AB1F5A3E6C32F46306CF35D1 /* Localizable.strings */; }; AB1F5AC6C40D04601334C714 /* RSPMainPanelViewModel.m in Sources */ = {isa = PBXBuildFile; fileRef = AB1F528059374B00A14ABEA6 /* RSPMainPanelViewModel.m */; }; AB1F5B51FCBCD8A4BA37E11D /* RSPSketchService.m in Sources */ = {isa = PBXBuildFile; fileRef = AB1F56102291E01988CFD009 /* RSPSketchService.m */; }; AB1F5BB7A00E053D68B64BEA /* RSPMainPanelViewModel.h in Headers */ = {isa = PBXBuildFile; fileRef = AB1F5A135051E6AF90FDEEBA /* RSPMainPanelViewModel.h */; }; @@ -3046,7 +3047,6 @@ 0E49BAF91E7F0CDB00FCDDAE /* NSMenu-CHMenuAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSMenu-CHMenuAdditions.h"; sourceTree = ""; }; 0E49BAFA1E7F0CDB00FCDDAE /* NSMenu-ECLogging.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSMenu-ECLogging.h"; sourceTree = ""; }; 0E49BAFB1E7F0CDB00FCDDAE /* NSMenu-NSMenu_Blocks.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSMenu-NSMenu_Blocks.h"; sourceTree = ""; }; - 0E49BAFC1E7F0CDB00FCDDAE /* NSMenuDelegate-Protocol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSMenuDelegate-Protocol.h"; sourceTree = ""; }; 0E49BAFD1E7F0CDB00FCDDAE /* NSMenuItem-CHMenuItemAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSMenuItem-CHMenuItemAdditions.h"; sourceTree = ""; }; 0E49BAFE1E7F0CDB00FCDDAE /* NSMutableArray-NSMutableArray_CHBlocks.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSMutableArray-NSMutableArray_CHBlocks.h"; sourceTree = ""; }; 0E49BAFF1E7F0CDB00FCDDAE /* NSMutableArray-NSMutableArrayAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSMutableArray-NSMutableArrayAdditions.h"; sourceTree = ""; }; @@ -3130,7 +3130,6 @@ 0E49BB4D1E7F0CDD00FCDDAE /* NSTextViewDelegate-Protocol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSTextViewDelegate-Protocol.h"; sourceTree = ""; }; 0E49BB4E1E7F0CDD00FCDDAE /* NSTimer-NSTimer_Blocks.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSTimer-NSTimer_Blocks.h"; sourceTree = ""; }; 0E49BB4F1E7F0CDD00FCDDAE /* NSToolbar-CHToolbarExtensions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSToolbar-CHToolbarExtensions.h"; sourceTree = ""; }; - 0E49BB501E7F0CDD00FCDDAE /* NSToolbarDelegate-Protocol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSToolbarDelegate-Protocol.h"; sourceTree = ""; }; 0E49BB511E7F0CDD00FCDDAE /* NSTouchBarDelegate-Protocol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSTouchBarDelegate-Protocol.h"; sourceTree = ""; }; 0E49BB521E7F0CDD00FCDDAE /* NSTrackingArea-CHTrackingAreaExtensions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSTrackingArea-CHTrackingAreaExtensions.h"; sourceTree = ""; }; 0E49BB531E7F0CDD00FCDDAE /* NSURL-BCFoundation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSURL-BCFoundation.h"; sourceTree = ""; }; @@ -3161,7 +3160,6 @@ 0E49BB6C1E7F0CDE00FCDDAE /* NSViewController-MSNormalInspector.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSViewController-MSNormalInspector.h"; sourceTree = ""; }; 0E49BB6D1E7F0CDE00FCDDAE /* NSViewControllerPresentationAnimator-Protocol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSViewControllerPresentationAnimator-Protocol.h"; sourceTree = ""; }; 0E49BB6E1E7F0CDE00FCDDAE /* NSWindow-Chocolat.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSWindow-Chocolat.h"; sourceTree = ""; }; - 0E49BB6F1E7F0CDE00FCDDAE /* NSWindowDelegate-Protocol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSWindowDelegate-Protocol.h"; sourceTree = ""; }; 0E49BB701E7F0CDE00FCDDAE /* NSWorkspace-CHWorkspaceAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSWorkspace-CHWorkspaceAdditions.h"; sourceTree = ""; }; 0E49BB711E7F0CDE00FCDDAE /* NSXMLDocument-SVGDocument.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSXMLDocument-SVGDocument.h"; sourceTree = ""; }; 0E49BB721E7F0CDE00FCDDAE /* NSXMLElement-SVG.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSXMLElement-SVG.h"; sourceTree = ""; }; @@ -3294,6 +3292,9 @@ A898C3431E6DDCF200696573 /* RSPMain.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RSPMain.m; sourceTree = ""; }; A898C3461E6DDD4500696573 /* RSPHelper.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = RSPHelper.js; sourceTree = ""; }; A898C34A1E6DE6E900696573 /* RSPMainPanel.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; name = RSPMainPanel.xib; path = Views/RSPMainPanel.xib; sourceTree = ""; }; + A8A5D3C81F17609D004B2DD8 /* RSPItemsSearching.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RSPItemsSearching.h; path = Services/RSPItemsSearching.h; sourceTree = ""; }; + A8A5D3C91F17609D004B2DD8 /* RSPSearchItemsService.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RSPSearchItemsService.h; path = Services/RSPSearchItemsService.h; sourceTree = ""; }; + A8A5D3CA1F17609D004B2DD8 /* RSPSearchItemsService.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RSPSearchItemsService.m; path = Services/RSPSearchItemsService.m; sourceTree = ""; }; A8B390551EF9509500201623 /* AnalyticsWindow.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = AnalyticsWindow.xib; sourceTree = ""; }; A8B390561EF9509500201623 /* GoogleAnalyticsTracker.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GoogleAnalyticsTracker.h; sourceTree = ""; }; A8B390571EF9509500201623 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; @@ -3307,12 +3308,14 @@ A8B3905F1EF9509500201623 /* MPGoogleAnalyticsTracker.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPGoogleAnalyticsTracker.m; sourceTree = ""; }; A8B3906C1EF9639000201623 /* RSPItem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RSPItem.h; sourceTree = ""; }; A8B3906D1EF9639000201623 /* RSPItem.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RSPItem.m; sourceTree = ""; }; + AB1F51A52A1CFB43142EA724 /* Macros.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Macros.h; path = Config/Macros.h; sourceTree = ""; }; AB1F528059374B00A14ABEA6 /* RSPMainPanelViewModel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RSPMainPanelViewModel.m; path = Views/RSPMainPanelViewModel.m; sourceTree = ""; }; AB1F52B5C95939C09463B611 /* RSPBehanceService.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RSPBehanceService.m; path = Services/RSPBehanceService.m; sourceTree = ""; }; AB1F56102291E01988CFD009 /* RSPSketchService.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RSPSketchService.m; path = Services/RSPSketchService.m; sourceTree = ""; }; AB1F599110FB81A3142425F4 /* RSPBehanceService.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RSPBehanceService.h; path = Services/RSPBehanceService.h; sourceTree = ""; }; AB1F59B028621B306E86B41B /* RSPSketchService.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RSPSketchService.h; path = Services/RSPSketchService.h; sourceTree = ""; }; AB1F5A135051E6AF90FDEEBA /* RSPMainPanelViewModel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RSPMainPanelViewModel.h; path = Views/RSPMainPanelViewModel.h; sourceTree = ""; }; + AB1F5A3E6C32F46306CF35D1 /* Localizable.strings */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.strings; path = Localizable.strings; sourceTree = ""; }; AB1F5A44B2B11DF74D2F6B5D /* RSPLogger.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RSPLogger.h; path = Services/RSPLogger.h; sourceTree = ""; }; AB1F5C2588A781EC70B9C6F3 /* RSPLogger.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RSPLogger.m; path = Services/RSPLogger.m; sourceTree = ""; }; /* End PBXFileReference section */ @@ -4709,7 +4712,6 @@ 0E49BAF91E7F0CDB00FCDDAE /* NSMenu-CHMenuAdditions.h */, 0E49BAFA1E7F0CDB00FCDDAE /* NSMenu-ECLogging.h */, 0E49BAFB1E7F0CDB00FCDDAE /* NSMenu-NSMenu_Blocks.h */, - 0E49BAFC1E7F0CDB00FCDDAE /* NSMenuDelegate-Protocol.h */, 0E49BAFD1E7F0CDB00FCDDAE /* NSMenuItem-CHMenuItemAdditions.h */, 0E49BAFE1E7F0CDB00FCDDAE /* NSMutableArray-NSMutableArray_CHBlocks.h */, 0E49BAFF1E7F0CDB00FCDDAE /* NSMutableArray-NSMutableArrayAdditions.h */, @@ -4793,7 +4795,6 @@ 0E49BB4D1E7F0CDD00FCDDAE /* NSTextViewDelegate-Protocol.h */, 0E49BB4E1E7F0CDD00FCDDAE /* NSTimer-NSTimer_Blocks.h */, 0E49BB4F1E7F0CDD00FCDDAE /* NSToolbar-CHToolbarExtensions.h */, - 0E49BB501E7F0CDD00FCDDAE /* NSToolbarDelegate-Protocol.h */, 0E49BB511E7F0CDD00FCDDAE /* NSTouchBarDelegate-Protocol.h */, 0E49BB521E7F0CDD00FCDDAE /* NSTrackingArea-CHTrackingAreaExtensions.h */, 0E49BB531E7F0CDD00FCDDAE /* NSURL-BCFoundation.h */, @@ -4824,7 +4825,6 @@ 0E49BB6C1E7F0CDE00FCDDAE /* NSViewController-MSNormalInspector.h */, 0E49BB6D1E7F0CDE00FCDDAE /* NSViewControllerPresentationAnimator-Protocol.h */, 0E49BB6E1E7F0CDE00FCDDAE /* NSWindow-Chocolat.h */, - 0E49BB6F1E7F0CDE00FCDDAE /* NSWindowDelegate-Protocol.h */, 0E49BB701E7F0CDE00FCDDAE /* NSWorkspace-CHWorkspaceAdditions.h */, 0E49BB711E7F0CDE00FCDDAE /* NSXMLDocument-SVGDocument.h */, 0E49BB721E7F0CDE00FCDDAE /* NSXMLElement-SVG.h */, @@ -4891,9 +4891,12 @@ 0E5D16821E86C07F00E1F578 /* Services */ = { isa = PBXGroup; children = ( + A8A5D3C81F17609D004B2DD8 /* RSPItemsSearching.h */, + A8A5D3C91F17609D004B2DD8 /* RSPSearchItemsService.h */, + A8A5D3CA1F17609D004B2DD8 /* RSPSearchItemsService.m */, AB1F597A505B6D98C6245182 /* Sketch */, AB1F57352BBE83BD85B2448D /* Search */, - AB1F51A9B6F7D75EFC3F8965 /* Helpers */, + AB1F51A9B6F7D75EFC3F8965 /* Logger */, ); name = Services; sourceTree = ""; @@ -5040,6 +5043,7 @@ A8951ED51EE155610025F930 /* search_disabled@2x.png */, A8951ED61EE155610025F930 /* search_enabled.png */, A8951ED71EE155610025F930 /* search_enabled@2x.png */, + AB1F5DD69070792831AF7B66 /* Localization */, ); name = Resources; sourceTree = ""; @@ -5121,13 +5125,13 @@ path = Model; sourceTree = ""; }; - AB1F51A9B6F7D75EFC3F8965 /* Helpers */ = { + AB1F51A9B6F7D75EFC3F8965 /* Logger */ = { isa = PBXGroup; children = ( AB1F5C2588A781EC70B9C6F3 /* RSPLogger.m */, AB1F5A44B2B11DF74D2F6B5D /* RSPLogger.h */, ); - name = Helpers; + name = Logger; sourceTree = ""; }; AB1F57352BBE83BD85B2448D /* Search */ = { @@ -5149,6 +5153,15 @@ name = Sketch; sourceTree = ""; }; + AB1F5DD69070792831AF7B66 /* Localization */ = { + isa = PBXGroup; + children = ( + AB1F5A3E6C32F46306CF35D1 /* Localizable.strings */, + AB1F51A52A1CFB43142EA724 /* Macros.h */, + ); + name = Localization; + sourceTree = ""; + }; /* End PBXGroup section */ /* Begin PBXHeadersBuildPhase section */ @@ -5221,6 +5234,7 @@ 0E49BFAE1E7F0CE200FCDDAE /* MSShapeChange.h in Headers */, 0E49C05E1E7F0CE300FCDDAE /* MSToggleBorderAction.h in Headers */, 0E49BD941E7F0CE100FCDDAE /* MSCloudContainerViewController.h in Headers */, + A8A5D3CB1F17609D004B2DD8 /* RSPItemsSearching.h in Headers */, 0E49BE4B1E7F0CE100FCDDAE /* MSGradientEventHandler.h in Headers */, 0E49BEFB1E7F0CE200FCDDAE /* MSMirrorAction.h in Headers */, 0E49BD451E7F0CE000FCDDAE /* MSArtboardPresetCollection.h in Headers */, @@ -5294,7 +5308,6 @@ 0E49BC711E7F0CE000FCDDAE /* AFMultipartFormData-Protocol.h in Headers */, 0E49BBD41E7F0CE000FCDDAE /* _MSImmutableExportPreset.h in Headers */, 0E49BFB71E7F0CE200FCDDAE /* MSShapePath-Protocol.h in Headers */, - 0E49C1801E7F0CE400FCDDAE /* NSWindowDelegate-Protocol.h in Headers */, 0E49BDBC1E7F0CE100FCDDAE /* MSColorInspectorSection.h in Headers */, 0E49BF001E7F0CE200FCDDAE /* MSMirrorViewController.h in Headers */, 0E49BECD1E7F0CE200FCDDAE /* MSLayerCachedImage.h in Headers */, @@ -5329,7 +5342,6 @@ 0E49BDDA1E7F0CE100FCDDAE /* MSCurveModeMirroredAction.h in Headers */, 0E49C1051E7F0CE400FCDDAE /* NSImageRep-MSSmallerArchiving.h in Headers */, 0E49C0AA1E7F0CE300FCDDAE /* NSArray-CloudAPISigning.h in Headers */, - 0E49C10D1E7F0CE400FCDDAE /* NSMenuDelegate-Protocol.h in Headers */, 0E49BF4F1E7F0CE200FCDDAE /* MSPersistentAssetCollection.h in Headers */, 0E49BCF61E7F0CE000FCDDAE /* ECLogChannel.h in Headers */, 0E49C1231E7F0CE400FCDDAE /* NSObject-NSObject_SmallBlocks.h in Headers */, @@ -5658,6 +5670,7 @@ 0E49BBFD1E7F0CE000FCDDAE /* _MSImmutableTextLayer.h in Headers */, 0E49BF251E7F0CE200FCDDAE /* MSNormalEventHandler.h in Headers */, 0E49BE3E1E7F0CE100FCDDAE /* MSFolderMonitor.h in Headers */, + A8A5D3CC1F17609D004B2DD8 /* RSPSearchItemsService.h in Headers */, A898C3441E6DDCF200696573 /* RSPMain.h in Headers */, 0E49C18E1E7F0CE400FCDDAE /* SMKMirrorConnectionsControllerDelegate-Protocol.h in Headers */, 0E49BC721E7F0CE000FCDDAE /* AFNetworkReachabilityManager.h in Headers */, @@ -6067,7 +6080,6 @@ 0E49C0731E7F0CE300FCDDAE /* MSTreeDiff.h in Headers */, 0E49BD061E7F0CE000FCDDAE /* FBBezierGraph.h in Headers */, 0E49C0D31E7F0CE300FCDDAE /* NSComboBoxDataSource-Protocol.h in Headers */, - 0E49C1611E7F0CE400FCDDAE /* NSToolbarDelegate-Protocol.h in Headers */, 0E49C14A1E7F0CE400FCDDAE /* NSString-NSString_Color.h in Headers */, 0E49BC821E7F0CE000FCDDAE /* BCCache.h in Headers */, 0E49BE3D1E7F0CE100FCDDAE /* MSFlipVerticalAction.h in Headers */, @@ -6829,6 +6841,7 @@ A8951EE01EE155610025F930 /* search_bar.png in Resources */, 0EC09B811E9C16180001DEF9 /* PhotoCollectionViewItem.xib in Resources */, A898C34B1E6DE6E900696573 /* RSPMainPanel.xib in Resources */, + AB1F59B21ABC5D245827E668 /* Localizable.strings in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -6851,6 +6864,7 @@ 0EC09BCC1E9C1EB40001DEF9 /* SDWebImageDownloader.m in Sources */, A8B390681EF9509500201623 /* MPAnalyticsParamBuilder.m in Sources */, A8951EC91EE14B690025F930 /* Config.m in Sources */, + A8A5D3CD1F17609D004B2DD8 /* RSPSearchItemsService.m in Sources */, 0EC09BC81E9C1EB40001DEF9 /* SDWebImageCompat.m in Sources */, 0EC09BE11E9C1EB40001DEF9 /* UIView+WebCache.m in Sources */, 0EC09BD31E9C1EB40001DEF9 /* SDWebImagePrefetcher.m in Sources */, diff --git a/source/SketchPlugin/Config/Config.h b/source/SketchPlugin/Config/Config.h index 3f60f4b..c734706 100644 --- a/source/SketchPlugin/Config/Config.h +++ b/source/SketchPlugin/Config/Config.h @@ -9,7 +9,9 @@ #import #pragma mark - Config + typedef struct { + CGSize moodboardGridSize; CGSize artboardGridSize; @@ -17,25 +19,24 @@ typedef struct { NSEdgeInsets imagesInsets; NSEdgeInsets artboardInsets; + } RSPMoodboardConfig; /// /// return default config (size, insets etc) for moodboard extern RSPMoodboardConfig defaultMoodboardConfig(void); -#define DEFAULT_PANEL_SIZE CGSizeMake(970, 1076) + +extern CGSize const DefaultPanelSize; + #pragma mark - Keys -#define DOCUMENT_KEY @"document" + +extern NSString *const kSketchDocument; #pragma mark - View Const -#define MAIN_NIB @"RSPMainPanel" -#define CELL_NIB @"PhotoCollectionViewItem" -#define PANEL_THREAD_KEY @"rsp_toolbar" -#define DEBUG_PANEL_THREAD_KEY @"rsp_debug" -#define PROCESS_THREAD_KEY @"rsp_main" - -#pragma makr - String Literals -#define PageNameText @"Moodboard" -#define ArtboardNameText @"Moodboard %li" -#define GridHintText @"%i columns x %i rows" -#define SelectedHintText @"%lu images selected" + +extern NSString *const kPanelThread; + +extern NSString *const kDebugPanelThread; + +extern NSString *const kProcessThread; diff --git a/source/SketchPlugin/Config/Config.m b/source/SketchPlugin/Config/Config.m index 741ed74..feaed46 100644 --- a/source/SketchPlugin/Config/Config.m +++ b/source/SketchPlugin/Config/Config.m @@ -21,3 +21,19 @@ RSPMoodboardConfig defaultMoodboardConfig(void) { }; return DefaultMoodboardConfig; } + + +CGSize const DefaultPanelSize = {970, 1076}; + +#pragma mark - Keys + +NSString *const kSketchDocument = @"document"; + +#pragma mark - View Const + +NSString *const kPanelThread = @"rsp_toolbar"; + +NSString *const kDebugPanelThread = @"rsp_debug"; + +NSString *const kProcessThread = @"rsp_main"; + diff --git a/source/SketchPlugin/Config/Macros.h b/source/SketchPlugin/Config/Macros.h new file mode 100644 index 0000000..f4f17fd --- /dev/null +++ b/source/SketchPlugin/Config/Macros.h @@ -0,0 +1,12 @@ +// +// Macros.h +// SketchPlugin +// +// Created by aboyko on 7/13/17. +// Copyright © 2017 Reinvently. All rights reserved. +// +@import AppKit; + +static inline NSString *RSPLocalizedString(NSString *key) { + return NSLocalizedStringFromTableInBundle(key, nil, [NSBundle bundleWithIdentifier:@"com.reinvently.sketchPlugin.SketchPlugin"], @""); +} diff --git a/source/SketchPlugin/HTML/Sources/CSSAttributeSelector.m b/source/SketchPlugin/HTML/Sources/CSSAttributeSelector.m new file mode 100755 index 0000000..355d549 --- /dev/null +++ b/source/SketchPlugin/HTML/Sources/CSSAttributeSelector.m @@ -0,0 +1,111 @@ +// +// CSSAttributeSelector.m +// HTMLKit +// +// Created by Iska on 14/05/15. +// Copyright (c) 2015 BrainCookie. All rights reserved. +// + +#import "CSSAttributeSelector.h" +#import "HTMLElement.h" +#import "NSCharacterSet+HTMLKit.h" + +@interface CSSAttributeSelector () +{ + CSSAttributeSelectorType _type; + NSString *_name; + NSString *_value; +} +@end + +@implementation CSSAttributeSelector + ++ (instancetype)classSelector:(NSString *)className +{ + return [[self alloc] initWithType:CSSAttributeSelectorIncludes attributeName:@"class" attrbiuteValue:className]; +} + ++ (instancetype)idSelector:(NSString *)elementId +{ + return [[self alloc] initWithType:CSSAttributeSelectorExactMatch attributeName:@"id" attrbiuteValue:elementId]; +} + ++ (instancetype)hasAttributeSelector:(NSString *)attributeName +{ + return [[self alloc] initWithType:CSSAttributeSelectorExists attributeName:attributeName attrbiuteValue:@""]; +} + +- (instancetype)initWithType:(CSSAttributeSelectorType)type + attributeName:(NSString *)name + attrbiuteValue:(NSString *)value +{ + self = [super init]; + if (self) { + _type = type; + _name = [name copy]; + _value = value ? [value copy]: @""; + } + return self; +} + +- (BOOL)acceptElement:(HTMLElement *)element +{ + switch (_type) { + case CSSAttributeSelectorExists: + { + return !!element[_name]; + } + case CSSAttributeSelectorExactMatch: + { + return [element[_name] isEqualToString:_value]; + } + case CSSAttributeSelectorIncludes: + { + NSArray *components = [element[_name] componentsSeparatedByCharactersInSet:[NSCharacterSet HTMLWhitespaceCharacterSet]]; + return [components containsObject:_value]; + } + case CSSAttributeSelectorBegins: + { + return [element[_name] hasPrefix:_value]; + } + case CSSAttributeSelectorEnds: + { + return [element[_name] hasSuffix:_value]; + } + case CSSAttributeSelectorContains: + { + return [element[_name] containsString:_value]; + } + case CSSAttributeSelectorHyphen: + { + return [element[_name] isEqualToString:_value] || [element[_name] hasPrefix:[_value stringByAppendingString:@"-"]]; + } + case CSSAttributeSelectorNot: + { + return ![element[_name] isEqualToString:_value]; + } + default: + return NO; + } +} + +#pragma mark - Description + +- (NSString *)debugDescription +{ + if (self.type == CSSAttributeSelectorExists) { + return [NSString stringWithFormat:@"[%@]", self.name]; + } + + NSString *matcher = @{@(CSSAttributeSelectorExactMatch): @"=", + @(CSSAttributeSelectorIncludes): @"~=", + @(CSSAttributeSelectorBegins): @"^=", + @(CSSAttributeSelectorEnds): @"$=", + @(CSSAttributeSelectorContains): @"*=", + @(CSSAttributeSelectorHyphen): @"|=", + @(CSSAttributeSelectorNot): @"!="}[@(self.type)]; + + return [NSString stringWithFormat:@"[%@%@'%@']", self.name, matcher, self.value]; +} + +@end diff --git a/source/SketchPlugin/HTML/Sources/CSSCombinatorSelector.m b/source/SketchPlugin/HTML/Sources/CSSCombinatorSelector.m new file mode 100755 index 0000000..1a9b4c3 --- /dev/null +++ b/source/SketchPlugin/HTML/Sources/CSSCombinatorSelector.m @@ -0,0 +1,155 @@ +// +// CSSCombinatorSelector.m +// HTMLKit +// +// Created by Iska on 12/10/15. +// Copyright © 2015 BrainCookie. All rights reserved. +// + +#import "CSSCombinatorSelector.h" +#import "HTMLElement.h" +#import "HTMLNode+Private.h" + +#pragma mark - Declarations + +@interface CSSChildOfElementCombinatorSelector : CSSCombinatorSelector +@end + +@interface CSSDecendantOfElementCombinatorSelector : CSSCombinatorSelector +@end + +@interface CSSAdjacentSiblingCombinatorSelector : CSSCombinatorSelector +@end + +@interface CSSGeneralSiblingCombinatorSelector : CSSCombinatorSelector +@end + +#pragma mark - Base Combinator + +@interface CSSCombinatorSelector () +{ + CSSSelector *_selector; +} +@property (nonatomic, strong, readonly) CSSSelector *selector; +@end + +@implementation CSSCombinatorSelector +@synthesize selector = _selector; + ++ (instancetype)childOfElementCombinator:(CSSSelector *)selector +{ + return [[CSSChildOfElementCombinatorSelector alloc] initWithSelector:selector]; +} + ++ (instancetype)descendantOfElementCombinator:(CSSSelector *)selector +{ + return [[CSSDecendantOfElementCombinatorSelector alloc] initWithSelector:selector]; +} + ++ (instancetype)adjacentSiblingCombinator:(CSSSelector *)selector +{ + return [[CSSAdjacentSiblingCombinatorSelector alloc] initWithSelector:selector]; +} + ++ (instancetype)generalSiblingCombinator:(CSSSelector *)selector +{ + return [[CSSGeneralSiblingCombinatorSelector alloc] initWithSelector:selector]; +} + +- (instancetype)initWithSelector:(CSSSelector *)selector +{ + self = [super init]; + if (self) { + _selector = selector; + } + return self; +} + +@end + +#pragma mark - Child OfElement Combinator + +@implementation CSSChildOfElementCombinatorSelector + +- (BOOL)acceptElement:(HTMLElement *)element +{ + HTMLElement *parent = element.parentElement; + return parent != nil && [self.selector acceptElement:parent]; +} + +- (NSString *)debugDescription +{ + return [NSString stringWithFormat:@"%@ > ", self.selector.debugDescription]; +} + +@end + +#pragma mark - Decendant Of Element Combinator + +@implementation CSSDecendantOfElementCombinatorSelector + +- (BOOL)acceptElement:(HTMLElement *)element +{ + HTMLElement *parent = element.parentElement; + + while (parent != nil) { + if ([self.selector acceptElement:parent]) { + return YES; + } + parent = parent.parentElement; + } + + return NO; +} + +- (NSString *)debugDescription +{ + return [NSString stringWithFormat:@"%@ ", self.selector.debugDescription]; +} + +@end + +#pragma mark - Adjacent Sibling Combinator + +@implementation CSSAdjacentSiblingCombinatorSelector + +- (BOOL)acceptElement:(HTMLElement *)element +{ + HTMLNode *previous = element.previousSiblingElement; + if (previous == nil || previous.nodeType != HTMLNodeElement) { + return NO; + } + return [self.selector acceptElement:previous.asElement]; +} + +- (NSString *)debugDescription +{ + return [NSString stringWithFormat:@"%@ + ", self.selector.debugDescription]; +} + +@end + +#pragma mark - General Sibling Combinator + +@implementation CSSGeneralSiblingCombinatorSelector + +- (BOOL)acceptElement:(HTMLElement *)element +{ + HTMLNode *previous = element.previousSiblingElement; + + while (previous != nil && previous.nodeType == HTMLNodeElement) { + if ([self.selector acceptElement:previous.asElement]) { + return YES; + } + previous = previous.previousSiblingElement; + } + + return NO; +} + +- (NSString *)debugDescription +{ + return [NSString stringWithFormat:@"%@ ~ ", self.selector.debugDescription]; +} + +@end diff --git a/source/SketchPlugin/HTML/Sources/CSSCompoundSelector.m b/source/SketchPlugin/HTML/Sources/CSSCompoundSelector.m new file mode 100755 index 0000000..712d55f --- /dev/null +++ b/source/SketchPlugin/HTML/Sources/CSSCompoundSelector.m @@ -0,0 +1,99 @@ +// +// CSSCompoundSelector.m +// HTMLKit +// +// Created by Iska on 18/10/15. +// Copyright © 2015 BrainCookie. All rights reserved. +// + +#import "CSSCompoundSelector.h" + +#pragma mark - Declarations + +@interface CSSAndCompoundSelector : CSSCompoundSelector +@end + +@interface CSSOrCompoundSelector : CSSCompoundSelector +@end + +#pragma mark - Base Combinator + +@interface CSSCompoundSelector () +{ + NSMutableArray *_selectors; +} +@property (nonatomic, strong, readonly) NSArray *selectors; +@end + +@implementation CSSCompoundSelector +@synthesize selectors = _selectors; + ++ (instancetype)andSelector:(NSArray *)selectors +{ + return [[CSSAndCompoundSelector alloc] initWithSelectors:selectors]; +} + ++ (instancetype)orSelector:(NSArray *)selectors +{ + return [[CSSOrCompoundSelector alloc] initWithSelectors:selectors]; +} + +- (instancetype)initWithSelectors:(NSArray *)selectors +{ + self = [super init]; + if (self) { + _selectors = [[NSMutableArray alloc] initWithArray:selectors]; + } + return self; +} + +- (void)addSelector:(CSSSelector *)selector +{ + [_selectors addObject:selector]; +} + +@end + +#pragma mark - And Compound Selector + +@implementation CSSAndCompoundSelector + +- (BOOL)acceptElement:(HTMLElement *)element +{ + for (CSSSelector *selector in self.selectors) { + if (![selector acceptElement:element]) { + return NO; + } + } + return YES; +} + +- (NSString *)debugDescription +{ + NSArray *descriptions = [self.selectors valueForKey:@"debugDescription"]; + return [descriptions componentsJoinedByString:@""]; +} + +@end + +#pragma mark - Or Compound Selector + +@implementation CSSOrCompoundSelector + +- (BOOL)acceptElement:(HTMLElement *)element +{ + for (CSSSelector *selector in self.selectors) { + if ([selector acceptElement:element]) { + return YES; + } + } + return NO; +} + +- (NSString *)debugDescription +{ + NSArray *descriptions = [self.selectors valueForKey:@"debugDescription"]; + return [descriptions componentsJoinedByString:@","]; +} + +@end diff --git a/source/SketchPlugin/HTML/Sources/CSSInputStream.m b/source/SketchPlugin/HTML/Sources/CSSInputStream.m new file mode 100755 index 0000000..f1fc03b --- /dev/null +++ b/source/SketchPlugin/HTML/Sources/CSSInputStream.m @@ -0,0 +1,138 @@ +// +// CSSInputStream.m +// HTMLKit +// +// Created by Iska on 07/06/15. +// Copyright (c) 2015 BrainCookie. All rights reserved. +// + +#import "CSSInputStream.h" +#import "CSSCodePoints.h" + +@interface HTMLInputStreamReader () +- (void)emitParseError:(NSString *)reason; +@end + +@implementation CSSInputStream + +- (void)consumeWhitespace +{ + while (isWhitespace(self.nextInputCharacter)) { + [self consumeNextInputCharacter]; + } +} + +- (NSString *)consumeIdentifier +{ + if (!isValidIdentifierStart([self inputCharacterPointAtOffset:0], + [self inputCharacterPointAtOffset:1], + [self inputCharacterPointAtOffset:2])) { + return nil; + } + + CFMutableStringRef value = CFStringCreateMutable(kCFAllocatorDefault, 0); + + while (YES) { + UTF32Char codePoint = [self consumeNextInputCharacter]; + if (codePoint == EOF) { + break; + } else if (isName(codePoint)) { + AppendCodePoint(value, codePoint); + } else if (isValidEscape(codePoint, [self inputCharacterPointAtOffset:1])) { + UTF32Char escapedCodePoint = [self consumeEscapedCodePoint]; + AppendCodePoint(value, escapedCodePoint); + } else { + [self reconsumeCurrentInputCharacter]; + break; + } + } + + if (CFStringGetLength(value) > 0) { + return (__bridge_transfer NSString *)value; + } + + CFRelease(value); + return nil; +} + +- (NSString *)consumeStringWithEndingCodePoint:(UTF32Char)endingCodePoint +{ + CFMutableStringRef value = CFStringCreateMutable(kCFAllocatorDefault, 0); + + while (YES) { + UTF32Char codePoint = [self consumeNextInputCharacter]; + if (codePoint == endingCodePoint) { + break; + } + + switch (codePoint) { + case EOF: + break; + case LINE_FEED: + [self emitParseError:@"New-line character (0x000A) in CSS attribute value"]; + [self reconsumeCurrentInputCharacter]; + break; + case REVERSE_SOLIDUS: + { + UTF32Char next = self.nextInputCharacter; + if (next == EOF) { + continue; + } else if (next == LINE_FEED) { + [self consumeNextInputCharacter]; + } else { + UTF32Char escapedCodePoint = [self consumeNextInputCharacter]; + AppendCodePoint(value, escapedCodePoint); + } + } + default: + AppendCodePoint(value, codePoint); + break; + } + } + + if (CFStringGetLength(value) > 0) { + return (__bridge_transfer NSString *)value; + } + + CFRelease(value); + return nil; +} + +- (UTF32Char)consumeEscapedCodePoint +{ + UTF32Char codePoint = [self consumeNextInputCharacter]; + + if (isHexDigit(codePoint)) { + CFMutableStringRef hexString = CFStringCreateMutable(kCFAllocatorDefault, 6); + AppendCodePoint(hexString, codePoint); + + while (isHexDigit(self.nextInputCharacter) && CFStringGetLength(hexString) <= 6) { + UniChar codePoint = [self consumeNextInputCharacter]; + CFStringAppendCharacters(hexString, &codePoint, 1); + } + + if (isWhitespace(self.nextInputCharacter)) { + [self consumeNextInputCharacter]; + } + + NSScanner *scanner = [NSScanner scannerWithString:(__bridge_transfer NSString *)(hexString)]; + unsigned int number; + [scanner scanHexInt:&number]; + + return isValidEscapedCodePoint(number) ? number : REPLACEMENT_CHARACTER; + } else if (codePoint == EOF) { + return REPLACEMENT_CHARACTER; + } + + return codePoint; +} + +- (NSString *)consumeCombinator +{ + NSString *combinator = [self consumeCharactersInString:@" >+~"]; + combinator = [combinator stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]; + + return combinator; +} + +@end diff --git a/source/SketchPlugin/HTML/Sources/CSSNthExpressionParser.m b/source/SketchPlugin/HTML/Sources/CSSNthExpressionParser.m new file mode 100755 index 0000000..392acb4 --- /dev/null +++ b/source/SketchPlugin/HTML/Sources/CSSNthExpressionParser.m @@ -0,0 +1,50 @@ +// +// CSSNthExpression.m +// HTMLKit +// +// Created by Iska on 10/10/15. +// Copyright © 2015 BrainCookie. All rights reserved. +// + +#import "CSSNthExpressionParser.h" +#import "CSSCodePoints.h" +#import "NSString+HTMLKit.h" +#import "NSCharacterSet+HTMLKit.h" + +@implementation CSSNthExpressionParser + ++ (CSSNthExpression)parseExpression:(NSString *)expression +{ + NSCharacterSet *whitespace = [NSCharacterSet whitespaceAndNewlineCharacterSet]; + + NSString *string = [expression.lowercaseString copy]; + string = [[string stringByTrimmingCharactersInSet:whitespace] copy]; + + if ([string isEqualToStringIgnoringCase:@"odd"]) { + return CSSNthExpressionOdd; + } else if ([string isEqualToStringIgnoringCase:@"even"]) { + return CSSNthExpressionEven; + } + + NSCharacterSet *set = [[NSCharacterSet CSSNthExpressionCharacterSet] invertedSet]; + if ([string rangeOfCharacterFromSet:set].location != NSNotFound) { + return CSSNthExpressionMake(0, 0); + } + NSArray *parts = [string componentsSeparatedByString:@"n"]; + + if (parts.count == 1) { + NSInteger b = [parts[0] integerValue]; + return CSSNthExpressionMake(0, b); + } else if (parts.count == 2) { + NSInteger a = [parts[0] integerValue]; + if (a == 0) { + a = [parts[0] isEqualToString:@"-"] ? -1 : 1; + } + NSInteger b = [parts[1] integerValue]; + return CSSNthExpressionMake(a, b); + } else { + return CSSNthExpressionMake(0, 0); + } +} + +@end diff --git a/source/SketchPlugin/HTML/Sources/CSSNthExpressionSelector.m b/source/SketchPlugin/HTML/Sources/CSSNthExpressionSelector.m new file mode 100755 index 0000000..9f74f8b --- /dev/null +++ b/source/SketchPlugin/HTML/Sources/CSSNthExpressionSelector.m @@ -0,0 +1,131 @@ +// +// CSSNthExpressionSelector.m +// HTMLKit +// +// Created by Iska on 10/10/15. +// Copyright © 2015 BrainCookie. All rights reserved. +// + +#import "CSSNthExpressionSelector.h" +#import "HTMLElement.h" +#import "HTMLNode+Private.h" + +#pragma mark - Nth-Expression + +const CSSNthExpression CSSNthExpressionOdd = (CSSNthExpression) { + .an = 2, .b = 1 +}; + +const CSSNthExpression CSSNthExpressionEven = (CSSNthExpression) { + .an = 2, .b = 0 +}; + +NSString * _Nonnull NSStringFromNthExpression(CSSNthExpression expression) +{ + if (expression.an == 0 && expression.b == 0) { + return @"invalid"; + } + + if (expression.an == 0) { + return [NSString stringWithFormat:@"%ld", (long)expression.b]; + } + if (expression.b == 0) { + return [NSString stringWithFormat:@"%ldn", (long)expression.an]; + } + + return [NSString stringWithFormat:@"%ldn%+ld", (long)expression.an, (long)expression.b]; +} + +#pragma mark - Implementation + +NSInteger computeIndex(NSEnumerator *enumerator, HTMLElement *element) +{ + NSInteger index = 0; + for (HTMLNode *node in enumerator) { + if (node.nodeType != HTMLNodeElement) { + continue; + } + + if ([node.asElement.tagName isEqualToString:element.tagName]) { + index++; + } + + if (node == element) { + break; + } + } + + return index; +} + +@interface CSSNthExpressionSelector () +{ + NSString *_className; + CSSNthExpression _expression; + NSInteger (^ _computeIndex)(HTMLElement *); +} +@end + +@implementation CSSNthExpressionSelector +@synthesize expression = _expression; +@synthesize className = _className; + ++ (instancetype)nthChildSelector:(CSSNthExpression)expression +{ + return [[self alloc] initWithClassName:@"nth-child" expression:expression block:^NSInteger(HTMLElement *element) { + return [element.parentElement indexOfChildElement:element] + 1; + }]; +} + ++ (instancetype)nthLastChildSelector:(CSSNthExpression)expression +{ + return [[self alloc] initWithClassName:@"nth-last-child" expression:expression block:^NSInteger(HTMLElement *element) { + return element.parentElement.childElementsCount - [element.parentElement indexOfChildElement:element]; + }]; +} + ++ (instancetype)nthOfTypeSelector:(CSSNthExpression)expression +{ + return [[self alloc] initWithClassName:@"nth-of-type" expression:expression block:^NSInteger(HTMLElement *element) { + return computeIndex(element.parentElement.childNodes.array.objectEnumerator, element); + }]; +} + ++ (instancetype)nthLastOfTypeSelector:(CSSNthExpression)expression +{ + return [[self alloc] initWithClassName:@"nth-last-of-type" expression:expression block:^NSInteger(HTMLElement *element) { + return computeIndex(element.parentElement.childNodes.array.reverseObjectEnumerator, element); + }]; +} + +- (instancetype)initWithClassName:(NSString *)className + expression:(CSSNthExpression)expression + block:(NSInteger (^)(HTMLElement *element))block +{ + self = [super init]; + if (self) { + _className = [className copy]; + _expression = expression; + _computeIndex = [block copy]; + } + return self; +} + +- (BOOL)acceptElement:(HTMLElement *)element +{ + NSInteger index = _computeIndex(element); + + if (_expression.an == 0) { + return index == _expression.b; + } else { + NSInteger diff = (index - _expression.b); + return (diff * _expression.an >= 0) && (diff % _expression.an == 0); + } +} + +- (NSString *)debugDescription +{ + return [NSString stringWithFormat:@":%@(%@)", self.className, NSStringFromNthExpression(self.expression)]; +} + +@end diff --git a/source/SketchPlugin/HTML/Sources/CSSPseudoClassSelector.m b/source/SketchPlugin/HTML/Sources/CSSPseudoClassSelector.m new file mode 100755 index 0000000..3471670 --- /dev/null +++ b/source/SketchPlugin/HTML/Sources/CSSPseudoClassSelector.m @@ -0,0 +1,46 @@ +// +// CSSPseudoClassSelector.m +// HTMLKit +// +// Created by Iska on 06/10/15. +// Copyright © 2015 BrainCookie. All rights reserved. +// + +#import "CSSPseudoClassSelector.h" + +@interface CSSPseudoClassSelector () +{ + NSString *_className; + CSSSelector *_selector; +} +@end + +@implementation CSSPseudoClassSelector +@synthesize className = _className; + +- (instancetype)initWithClassName:(NSString *)className selector:(CSSSelector *)selector +{ + self = [super init]; + if (self) { + _className = [className copy]; + _selector = selector; + } + return self; +} + +-(BOOL)acceptElement:(HTMLElement *)element +{ + return [_selector acceptElement:element]; +} + +- (NSString *)debugDescription +{ + return [NSString stringWithFormat:@":%@", self.className]; +} + +- (NSString *)description +{ + return [NSString stringWithFormat:@"<%@: %p '%@'>", self.class, self, self.debugDescription]; +} + +@end diff --git a/source/SketchPlugin/HTML/Sources/CSSPseudoFunctionSelector.m b/source/SketchPlugin/HTML/Sources/CSSPseudoFunctionSelector.m new file mode 100755 index 0000000..f4bbbe0 --- /dev/null +++ b/source/SketchPlugin/HTML/Sources/CSSPseudoFunctionSelector.m @@ -0,0 +1,91 @@ +// +// CSSPseudoFunctionSelector.m +// HTMLKit +// +// Created by Iska on 07/10/15. +// Copyright © 2015 BrainCookie. All rights reserved. +// + +#import "CSSPseudoFunctionSelector.h" +#import "HTMLElement.h" +#import "HTMLNode+Private.h" + +#pragma mark - Declarations + +@interface CSSNotSelector : CSSPseudoFunctionSelector +@end + +@interface CSSHasSelector : CSSPseudoFunctionSelector +@end + +#pragma mark - Base Function Selector + +@interface CSSPseudoFunctionSelector () +{ + CSSSelector *_selector; +} +@property (nonatomic, strong, readonly) CSSSelector *selector; +@end + +@implementation CSSPseudoFunctionSelector +@synthesize selector = _selector; + ++ (instancetype)notSelector:(CSSSelector *)selector +{ + return [[CSSNotSelector alloc] initWithSelector:selector]; +} + ++ (instancetype)hasSelector:(CSSSelector *)selector +{ + return [[CSSHasSelector alloc] initWithSelector:selector]; +} + +- (instancetype)initWithSelector:(CSSSelector *)selector +{ + self = [super init]; + if (self) { + _selector = selector; + } + return self; +} + +@end + +#pragma mark - Not Selector + +@implementation CSSNotSelector + +- (BOOL)acceptElement:(HTMLElement *)element +{ + return ![self.selector acceptElement:element]; +} + +- (NSString *)debugDescription +{ + return [NSString stringWithFormat:@":not(%@)", self.selector.debugDescription]; +} + +@end + +#pragma mark - Has Selector + +@implementation CSSHasSelector + +- (BOOL)acceptElement:(HTMLElement *)element +{ + HTMLNodeIterator *iterator = [element nodeIteratorWithShowOptions:HTMLNodeFilterShowAll filter:nil]; + for (HTMLNode *descendant in iterator) { + if (descendant.nodeType == HTMLNodeElement && [self.selector acceptElement:descendant.asElement]) { + return YES; + } + } + + return NO; +} + +- (NSString *)debugDescription +{ + return [NSString stringWithFormat:@":has(%@)", self.selector.debugDescription]; +} + +@end diff --git a/source/SketchPlugin/HTML/Sources/CSSSelector.m b/source/SketchPlugin/HTML/Sources/CSSSelector.m new file mode 100755 index 0000000..14097a7 --- /dev/null +++ b/source/SketchPlugin/HTML/Sources/CSSSelector.m @@ -0,0 +1,44 @@ +// +// CSSSelector.m +// HTMLKit +// +// Created by Iska on 15/10/15. +// Copyright (c) 2015 BrainCookie. All rights reserved. +// + +#import +#import "CSSSelector.h" +#import "CSSSelectorParser.h" + +@implementation CSSSelector + ++ (instancetype)selectorWithString:(NSString *)string +{ + NSError *error = nil; + CSSSelector *instance = [CSSSelectorParser parseSelector:string error:&error]; + if (error) { + return nil; + } + return instance; +} + +- (BOOL)acceptElement:(HTMLElement *)element +{ + [self doesNotRecognizeSelector:_cmd]; + return NO; +} + +#pragma mark - Description + +- (NSString *)debugDescription +{ + [self doesNotRecognizeSelector:_cmd]; + return @""; +} + +- (NSString *)description +{ + return [NSString stringWithFormat:@"<%@: %p '%@'>", self.class, self, self.debugDescription]; +} + +@end diff --git a/source/SketchPlugin/HTML/Sources/CSSSelectorBlock.m b/source/SketchPlugin/HTML/Sources/CSSSelectorBlock.m new file mode 100755 index 0000000..c8d44d6 --- /dev/null +++ b/source/SketchPlugin/HTML/Sources/CSSSelectorBlock.m @@ -0,0 +1,40 @@ +// +// CSSSelectorBlock.m +// HTMLKit +// +// Created by Iska on 20/10/15. +// Copyright © 2015 BrainCookie. All rights reserved. +// + +#import "CSSSelectorBlock.h" + +@interface CSSSelectorBlock () +{ + NSString *_name; + BOOL (^ _acceptBlock)(HTMLElement *); +} +@end + +@implementation CSSSelectorBlock + +- (instancetype)initWithName:(NSString *)name block:(BOOL (^)(HTMLElement *))block +{ + self = [super init]; + if (self) { + _name = [name copy]; + _acceptBlock = [block copy]; + } + return self; +} + +- (BOOL)acceptElement:(HTMLElement *)element +{ + return _acceptBlock ? _acceptBlock(element) : NO; +} + +- (NSString *)debugDescription +{ + return _name; +} + +@end diff --git a/source/SketchPlugin/HTML/Sources/CSSSelectorParser.m b/source/SketchPlugin/HTML/Sources/CSSSelectorParser.m new file mode 100755 index 0000000..b3f0f63 --- /dev/null +++ b/source/SketchPlugin/HTML/Sources/CSSSelectorParser.m @@ -0,0 +1,426 @@ +// +// CSSSelectorParser.m +// HTMLKit +// +// Created by Iska on 02/10/15. +// Copyright © 2015 BrainCookie. All rights reserved. +// + +#import "CSSSelectorParser.h" +#import "CSSInputStream.h" +#import "CSSCodePoints.h" +#import "CSSSelectors.h" +#import "NSString+HTMLKit.h" +#import "NSCharacterSet+HTMLKit.h" +#import "CSSNthExpressionParser.h" +#import "CSSCompoundSelector.h" +#import "HTMLKitErrorDomain.h" + +@interface CSSSelectorParser () +{ + NSString *_string; + CSSInputStream *_inputStream; + NSUInteger _location; + + NSMutableArray *_selectors; +} +@end + +@implementation CSSSelectorParser + ++ (CSSSelector *)parseSelector:(NSString *)string error:(NSError * __autoreleasing *)error +{ + CSSSelectorParser *parser = [[CSSSelectorParser alloc] initWithString:string]; + CSSSelector *selector = [parser parse:error]; + + return selector; +} + +#pragma mark - Init + +- (instancetype)initWithString:(NSString *)string +{ + self = [super init]; + if (self) { + _string = [self preprocessInput:string]; + _location = 0; + } + return self; +} + +- (NSString *)preprocessInput:(NSString *)string +{ + string = [string stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]; + string = [string stringByReplacingOccurrencesOfString:@"\r\n" withString:@"\n"]; + string = [string stringByReplacingOccurrencesOfString:@"\r" withString:@"\n"]; + string = [string stringByReplacingOccurrencesOfString:@"\f" withString:@"\n"]; + string = [string stringByReplacingOccurrencesOfString:@"\0" withString:@"\uFFFD"]; + + return string; +} + +#pragma mark - Errors + +- (void)emitError:(NSError * __autoreleasing *)error reason:(NSString *)reason +{ + [self emitError:error reason:reason location:_location + _inputStream.currentLocation]; +} + +- (void)emitError:(NSError * __autoreleasing *)error reason:(NSString *)reason location:(NSUInteger)location +{ + NSDictionary *userInfo = @{ + NSLocalizedDescriptionKey: @"Error parsing selector", + NSLocalizedFailureReasonErrorKey: reason, + CSSSelectorStringKey: _string, + CSSSelectorErrorLocationKey: @(location) + }; + + if(error && *error == nil) { + *error = [NSError errorWithDomain:HTMLKitSelectorErrorDomain code:HTMLKitSelectorParseError userInfo:userInfo]; + } +} + +#pragma mark - Parsing + +- (CSSSelector *)parse:(NSError * __autoreleasing *)error +{ + if (_string.length == 0) { + [self emitError:error reason:@"Empty selector" location:0]; + return nil; + } + + NSArray *allSubSelectors = [_string componentsSeparatedByString:@","]; + NSMutableArray *parsed = [NSMutableArray array]; + + for (NSString *subSelector in allSubSelectors) { + if ([subSelector isEqualToString:@""]) { + [self emitError:error reason:@"Empty selector" location:_location]; + break; + } + + CSSSelector *selector = [self parseSelector:subSelector error:error]; + if (selector == nil) { + break; + } + [parsed addObject:selector]; + + _location += subSelector.length; + } + + if (error && *error != nil) { + return nil; + } + + if (parsed.count > 1) { + return anyOf(parsed); + } + + return parsed.firstObject; +} + +- (CSSSelector *)parseSelector:(NSString *)selectorString error:(NSError * __autoreleasing *)error +{ + _inputStream = [[CSSInputStream alloc] initWithString:selectorString]; + [_inputStream consumeWhitespace]; + + CSSSelector *result = nil; + + while (YES) { + CSSSelector *selector = [self parseSequenceOfSimpleSelectors:error]; + if (selector == nil) { + break; + } + + result = result ? allOf(@[result, selector]) : selector; + + UTF32Char next = _inputStream.nextInputCharacter; + + if (isCombinator(next)) { + NSString *combinator = [_inputStream consumeCombinator]; + + if ([combinator isEqualToString:@""]) { + result = descendantOfElementSelector(result); + } else if ([combinator isEqualToString:@">"]) { + result = childOfElementSelector(result); + } else if ([combinator isEqualToString:@"+"]) { + result = adjacentSiblingSelector(result); + } else if ([combinator isEqualToString:@"~"]) { + result = generalSiblingSelector(result); + } + } + } + + return result; +} + +- (CSSSelector *)parseSequenceOfSimpleSelectors:(NSError * __autoreleasing *)error +{ + NSMutableArray *selectors = [NSMutableArray array]; + + CSSSelector *typeSelector = [self parseTypeSelector:error]; + if (typeSelector != nil) { + [selectors addObject:typeSelector]; + } + + while (YES) { + UTF32Char next = _inputStream.nextInputCharacter; + if (next == EOF || isCombinator(next)) { + break; + } + + CSSSelector *simpleSelector = [self parseSimpleSelector:error]; + if (simpleSelector == nil) { + return nil; + } + [selectors addObject:simpleSelector]; + } + + if (selectors.count > 1) { + return allOf(selectors); + } + + return selectors.firstObject; +} + +- (CSSSelector *)parseTypeSelector:(NSError * __autoreleasing *)error +{ + NSString *identifier = [_inputStream consumeIdentifier]; + if (identifier != nil) { + return typeSelector(identifier); + } + + if ([_inputStream consumeCharacter:ASTERIX]) { + return universalSelector(); + } + + return nil; +} + +- (CSSSelector *)parseSimpleSelector:(NSError * __autoreleasing *)error +{ + CSSSelector *typeSelector = [self parseTypeSelector:error]; + if (typeSelector != nil) { + return typeSelector; + } + + UTF32Char codePoint = [_inputStream consumeNextInputCharacter]; + switch (codePoint) { + case NUMBER_SIGN: + { + NSString *elementId = [_inputStream consumeIdentifier]; + if (elementId == nil) { + [self emitError:error reason:@"Invalid character"]; + return nil; + } + return idSelector(elementId); + } + case FULL_STOP: + { + NSString *className = [_inputStream consumeIdentifier]; + if (className == nil) { + [self emitError:error reason:@"Invalid character"]; + return nil; + } + return classSelector(className); + } + case LEFT_SQUARE_BRACKET: + { + return [self parseAttributeSelector:error]; + } + case COLON: + { + return [self parsePseudoSelector:error]; + } + default: + { + [self emitError:error reason:@"Invalid character"]; + return nil; + } + } +} + +- (CSSSelector *)parseAttributeSelector:(NSError * __autoreleasing *)error +{ + NSString *attribute = [_inputStream consumeIdentifier]; + if (attribute == nil) { + [self emitError:error reason:@"Invalid character" location:_location + _inputStream.currentLocation + 1]; + return nil; + } + [_inputStream consumeWhitespace]; + + CSSAttributeSelectorType type = CSSAttributeSelectorExists; + + NSString *operator = [_inputStream consumeCharactersInString:@"=~|^$*!"]; + + if ([operator isEqualToString:@"="]) { + type = CSSAttributeSelectorExactMatch; + } else if ([operator isEqualToString:@"~="]) { + type = CSSAttributeSelectorIncludes; + } else if ([operator isEqualToString:@"|="]) { + type = CSSAttributeSelectorHyphen; + } else if ([operator isEqualToString:@"^="]) { + type = CSSAttributeSelectorBegins; + } else if ([operator isEqualToString:@"$="]) { + type = CSSAttributeSelectorEnds; + } else if ([operator isEqualToString:@"*="]) { + type = CSSAttributeSelectorContains; + } else if ([operator isEqualToString:@"!="]) { + type = CSSAttributeSelectorNot; + } + + NSString *value = nil; + [_inputStream consumeWhitespace]; + + UTF32Char next = _inputStream.nextInputCharacter; + if (isQuote(next)) { + UTF32Char quote = [_inputStream consumeNextInputCharacter]; + value = [_inputStream consumeStringWithEndingCodePoint:quote]; + } else { + value = [_inputStream consumeIdentifier]; + } + + [_inputStream consumeWhitespace]; + + // Consume RIGHT_SQUARE_BRACKET + if (![_inputStream consumeCharacter:RIGHT_SQUARE_BRACKET]) { + [self emitError:error reason:@"Expected closing right square bracket ']'"]; + } + + if (type == CSSAttributeSelectorExists) { + return hasAttributeSelector(attribute); + } + + return attributeSelector(type, attribute, value); +} + +- (CSSSelector *)parsePseudoSelector:(NSError * __autoreleasing *)error +{ + NSString *pseudoClass = [_inputStream consumeIdentifier]; + + if ([pseudoClass hasPrefix:@"nth"]) { + [_inputStream consumeWhitespace]; + if (![_inputStream consumeCharacter:LEFT_PARENTHESIS]) { + [self emitError:error reason:@"Expected opening left parenthesis '('"]; + } + + NSString *functionExpression = [_inputStream consumeCharactersUpToString:@")"]; + CSSNthExpression expression = [CSSNthExpressionParser parseExpression:functionExpression]; + + [_inputStream consumeWhitespace]; + if (![_inputStream consumeCharacter:RIGHT_PARENTHESIS]) { + [self emitError:error reason:@"Expected closing right parenthesis ')'"]; + } + + if ([pseudoClass isEqualToString:@"nth-child"]) { + return nthChildSelector(expression); + } else if ([pseudoClass isEqualToString:@"nth-last-child"]) { + return nthLastChildSelector(expression); + } else if ([pseudoClass isEqualToString:@"nth-of-type"]) { + return nthOfTypeSelector(expression); + } else if ([pseudoClass isEqualToString:@"nth-last-of-type"]) { + return nthLastOfTypeSelector(expression); + } + } else if ([pseudoClass isEqualToString:@"not"]) { + [_inputStream consumeWhitespace]; + if (![_inputStream consumeCharacter:LEFT_PARENTHESIS]) { + [self emitError:error reason:@"Expected opening left parenthesis '('"]; + } + + CSSSelector *subSelector = [self parseSimpleSelector:error]; + [_inputStream consumeWhitespace]; + if (![_inputStream consumeCharacter:RIGHT_PARENTHESIS]) { + [self emitError:error reason:@"Expected closing right parenthesis ')'"]; + } + + return not(subSelector); + } else if ([pseudoClass isEqualToAny:@"lt", @"gt", @"eq", nil]) { + [_inputStream consumeWhitespace]; + if (![_inputStream consumeCharacter:LEFT_PARENTHESIS]) { + [self emitError:error reason:@"Expected opening left parenthesis '('"]; + } + + NSDecimal decimal; + if (![_inputStream consumeDecimalNumber:&decimal]) { + [self emitError:error reason:@"Expected a decimal number"]; + } + + [_inputStream consumeWhitespace]; + if (![_inputStream consumeCharacter:RIGHT_PARENTHESIS]) { + [self emitError:error reason:@"Expected closing right parenthesis ')'"]; + } + + NSDecimalNumber *number = [[NSDecimalNumber alloc] initWithDecimal:decimal]; + if ([pseudoClass isEqualToString:@"lt"]) { + return ltSelector(number.integerValue); + } else if ([pseudoClass isEqualToString:@"gt"]) { + return gtSelector(number.integerValue); + } else if ([pseudoClass isEqualToString:@"eq"]) { + return eqSelector(number.integerValue); + } + } else { + if ([pseudoClass isEqualToString:@"even"]) { + return evenSlector(); + } else if ([pseudoClass isEqualToString:@"odd"]) { + return oddSelector(); + } else if ([pseudoClass isEqualToString:@"first-child"]) { + return firstChildSelector(); + } else if ([pseudoClass isEqualToString:@"last-child"]) { + return lastChildSelector(); + } else if ([pseudoClass isEqualToString:@"first-of-type"]) { + return firstOfTypeSelector(); + } else if ([pseudoClass isEqualToString:@"last-of-type"]) { + return lastOfTypeSelector(); + } else if ([pseudoClass isEqualToString:@"only-child"]) { + return onlyChildSelector(); + } else if ([pseudoClass isEqualToString:@"only-of-type"]) { + return onlyOfTypeSelector(); + } else if ([pseudoClass isEqualToString:@"root"]) { + return rootSelector(); + } else if ([pseudoClass isEqualToString:@"empty"]) { + return emptySelector(); + } else if ([pseudoClass isEqualToString:@"link"]) { + return linkSelector(); + } else if ([pseudoClass isEqualToString:@"enabled"]) { + return enabledSelector(); + } else if ([pseudoClass isEqualToString:@"disabled"]) { + return disabledSelector(); + } else if ([pseudoClass isEqualToString:@"checked"]) { + return checkedSelector(); + } + + else if ([pseudoClass isEqualToString:@"button"]) { + return buttonSelector(); + } else if ([pseudoClass isEqualToString:@"checkbox"]) { + return checkboxSelector(); + } else if ([pseudoClass isEqualToString:@"file"]) { + return fileSelector(); + } else if ([pseudoClass isEqualToString:@"header"]) { + return headerSelector(); + } else if ([pseudoClass isEqualToString:@"image"]) { + return imageSelector(); + } else if ([pseudoClass isEqualToString:@"optional"]) { + return optionalSelector(); + } else if ([pseudoClass isEqualToString:@"parent"]) { + return parentSelector(); + } else if ([pseudoClass isEqualToString:@"password"]) { + return passwordSelector(); + } else if ([pseudoClass isEqualToString:@"radio"]) { + return radioSelector(); + } else if ([pseudoClass isEqualToString:@"reset"]) { + return resetSelector(); + } else if ([pseudoClass isEqualToString:@"submit"]) { + return submitSelector(); + } else if ([pseudoClass isEqualToString:@"text"]) { + return textSelector(); + } else if ([pseudoClass isEqualToString:@"required"]) { + return requiredSelector(); + } else if ([pseudoClass isEqualToString:@"reset"]) { + return resetSelector(); + } + } + NSString *reason = [NSString stringWithFormat:@"Unknown pseudo class: %@", pseudoClass]; + [self emitError:error reason:reason]; + return nil; +} + +@end diff --git a/source/SketchPlugin/HTML/Sources/CSSSelectors.m b/source/SketchPlugin/HTML/Sources/CSSSelectors.m new file mode 100755 index 0000000..55d9b0b --- /dev/null +++ b/source/SketchPlugin/HTML/Sources/CSSSelectors.m @@ -0,0 +1,177 @@ +// +// CSSSelectors.m +// HTMLKit +// +// Created by Iska on 19/10/15. +// Copyright © 2015 BrainCookie. All rights reserved. +// + +#import "CSSSelectors.h" +#import "CSSTypeSelector.h" +#import "CSSAttributeSelector.h" +#import "CSSPseudoClassSelector.h" +#import "CSSPseudoFunctionSelector.h" +#import "CSSNthExpressionSelector.h" +#import "CSSCombinatorSelector.h" +#import "CSSCompoundSelector.h" +#import "CSSSelectorBlock.h" + +#pragma mark - Type Selectors + +CSSSelector * universalSelector() +{ + return [CSSTypeSelector universalSelector]; +} + +CSSSelector * typeSelector(NSString *type) +{ + return [[CSSTypeSelector alloc] initWithType:type]; +} + +#pragma mark - Atribute Selectors + +CSSSelector * idSelector(NSString *elementId) +{ + return [CSSAttributeSelector idSelector:elementId]; +} + +CSSSelector * classSelector(NSString *className) +{ + return [CSSAttributeSelector classSelector:className]; +} + +CSSSelector * hasAttributeSelector(NSString *attribute) +{ + return [CSSAttributeSelector hasAttributeSelector:attribute]; +} + +CSSSelector * attributeSelector(CSSAttributeSelectorType type, + NSString *attribute, + NSString *value) +{ + return [[CSSAttributeSelector alloc] initWithType:type attributeName:attribute attrbiuteValue:value]; +} + +#pragma mark - Nth-Expression Selectors + +CSSSelector * nthChildSelector(CSSNthExpression expression) +{ + return [CSSNthExpressionSelector nthChildSelector:expression]; +} + +CSSSelector * nthLastChildSelector(CSSNthExpression expression) +{ + return [CSSNthExpressionSelector nthLastChildSelector:expression]; +} + +CSSSelector * nthOfTypeSelector(CSSNthExpression expression) +{ + return [CSSNthExpressionSelector nthOfTypeSelector:expression]; +} + +CSSSelector * nthLastOfTypeSelector(CSSNthExpression expression) +{ + return [CSSNthExpressionSelector nthLastOfTypeSelector:expression]; +} + +#pragma mark - Nth-Expression Shorthand + +CSSSelector * oddSelector() +{ + return namedPseudoSelector(@"odd", nthChildSelector(CSSNthExpressionOdd)); +} + +CSSSelector * evenSlector() +{ + return namedPseudoSelector(@"even", nthChildSelector(CSSNthExpressionEven)); +} + +CSSSelector * firstChildSelector() +{ + return namedPseudoSelector(@"first-child", nthChildSelector(CSSNthExpressionMake(0, 1))); +} + +CSSSelector * lastChildSelector() +{ + return namedPseudoSelector(@"last-child", nthLastChildSelector(CSSNthExpressionMake(0, 1))); +} + +CSSSelector * firstOfTypeSelector() +{ + return namedPseudoSelector(@"first-of-type", nthOfTypeSelector(CSSNthExpressionMake(0, 1))); +} + +CSSSelector * lastOfTypeSelector() +{ + return namedPseudoSelector(@"last-of-type", nthLastOfTypeSelector(CSSNthExpressionMake(0, 1))); +} + +CSSSelector * onlyChildSelector() +{ + return namedPseudoSelector(@"only-child", allOf(@[firstChildSelector(), lastChildSelector()])); +} + +CSSSelector * onlyOfTypeSelector() +{ + return namedPseudoSelector(@"only-of-type", allOf(@[firstOfTypeSelector(), lastOfTypeSelector()])); +} + +#pragma mark - Combinators + +CSSSelector * childOfElementSelector(CSSSelector *selector) +{ + return [CSSCombinatorSelector childOfElementCombinator:selector]; +} + +CSSSelector * descendantOfElementSelector(CSSSelector *selector) +{ + return [CSSCombinatorSelector descendantOfElementCombinator:selector]; +} + +CSSSelector * adjacentSiblingSelector(CSSSelector *selector) +{ + return [CSSCombinatorSelector adjacentSiblingCombinator:selector]; +} + +CSSSelector * generalSiblingSelector(CSSSelector *selector) +{ + return [CSSCombinatorSelector generalSiblingCombinator:selector]; +} + +#pragma mark - Pseudo Functions + +CSSSelector * not(CSSSelector *selector) +{ + return [CSSPseudoFunctionSelector notSelector:selector]; +} + +CSSSelector * has(CSSSelector *selector) +{ + return [CSSPseudoFunctionSelector hasSelector:selector]; +} + +#pragma mark - Compound Selectors + +CSSSelector * allOf( NSArray * selectors) +{ + return [CSSCompoundSelector andSelector:selectors]; +} + +CSSSelector * anyOf( NSArray * selectors) +{ + return [CSSCompoundSelector orSelector:selectors]; +} + +#pragma mark - Pseudo + +CSSSelector * namedPseudoSelector(NSString *name, CSSSelector *selector) +{ + return [[CSSPseudoClassSelector alloc] initWithClassName:name selector:selector]; +} + +#pragma mark - Block + +CSSSelector * namedBlockSelector(NSString *name, BOOL (^ acceptBlock)(HTMLElement *element)) +{ + return [[CSSSelectorBlock alloc] initWithName:name block:acceptBlock]; +} diff --git a/source/SketchPlugin/HTML/Sources/CSSStructuralPseudoSelectors.m b/source/SketchPlugin/HTML/Sources/CSSStructuralPseudoSelectors.m new file mode 100755 index 0000000..af99dea --- /dev/null +++ b/source/SketchPlugin/HTML/Sources/CSSStructuralPseudoSelectors.m @@ -0,0 +1,313 @@ +// +// CSSStructuralPseudoSelector.m +// HTMLKit +// +// Created by Iska on 11/10/15. +// Copyright © 2015 BrainCookie. All rights reserved. +// + +#import "CSSStructuralPseudoSelectors.h" +#import "CSSSelectors.h" +#import "HTMLElement.h" +#import "NSString+HTMLKit.h" + +#pragma mark - Elements + +CSSSelector * rootSelector() +{ + return namedBlockSelector(@":root", ^BOOL(HTMLElement * element) { + return element.parentElement == nil; + }); +} + +CSSSelector * emptySelector() +{ + return namedBlockSelector(@":empty", ^BOOL(HTMLElement * element) { + for (HTMLNode *child in element.childNodes) { + if (child.nodeType == HTMLNodeElement) { + return NO; + } else if (child.nodeType == HTMLNodeText && child.textContent.length > 0) { + return NO; + } + } + return YES; + }); +} + +CSSSelector * parentSelector() +{ + return namedBlockSelector(@":parent", ^BOOL(HTMLElement * element) { + return element.childNodesCount > 0; + }); +} + +CSSSelector * buttonSelector() +{ + return namedBlockSelector(@":button", ^BOOL(HTMLElement * _Nonnull element) { + if ([element.tagName isEqualToString:@"button"]) { + return YES; + } + if ([element.tagName isEqualToString:@"input"] && [element[@"type"] isEqualToString:@"button"]) { + return YES; + } + return NO; + }); +} + +CSSSelector * checkboxSelector() +{ + return namedBlockSelector(@":checkbox", ^BOOL(HTMLElement * _Nonnull element) { + if ([element[@"type"] isEqualToString:@"checkbox"]) { + return YES; + } + return NO; + }); +} + +CSSSelector * fileSelector() +{ + return namedBlockSelector(@":file", ^BOOL(HTMLElement * _Nonnull element) { + if ([element[@"type"] isEqualToString:@"file"]) { + return YES; + } + return NO; + }); +} + +CSSSelector * headerSelector() +{ + return namedBlockSelector(@":header", ^BOOL(HTMLElement * _Nonnull element) { + if ([element.tagName isEqualToAny:@"h1", @"h2", @"h3", @"h4", @"h5", @"h6", nil]) { + return YES; + } + return NO; + }); +} + +CSSSelector * imageSelector() +{ + return namedBlockSelector(@":image", ^BOOL(HTMLElement * _Nonnull element) { + if ([element[@"type"] isEqualToString:@"image"]) { + return YES; + } + return NO; + }); +} + +CSSSelector * inputSelector() +{ + return namedBlockSelector(@":input", ^BOOL(HTMLElement * _Nonnull element) { + if ([element.tagName isEqualToAny:@"button", @"input", @"select", @"textarea", nil]) { + return YES; + } + return NO; + }); +} + +CSSSelector * linkSelector() +{ + // https://html.spec.whatwg.org/multipage/scripting.html#selector-link + return namedBlockSelector(@":link", ^BOOL(HTMLElement * element) { + if ([element hasAttribute:@"href"]) { + return [element.tagName isEqualToAny:@"a", @"area", @"link", nil]; + } + return NO; + }); +} + +CSSSelector * passwordSelector() +{ + return namedBlockSelector(@":password", ^BOOL(HTMLElement * _Nonnull element) { + if ([element[@"type"] isEqualToString:@"password"]) { + return YES; + } + return NO; + }); +} + +CSSSelector * radioSelector() +{ + return namedBlockSelector(@":radio", ^BOOL(HTMLElement * _Nonnull element) { + if ([element[@"type"] isEqualToString:@"radio"]) { + return YES; + } + return NO; + }); +} + +CSSSelector * resetSelector() +{ + return namedBlockSelector(@":reset", ^BOOL(HTMLElement * _Nonnull element) { + if ([element[@"type"] isEqualToString:@"reset"]) { + return YES; + } + return NO; + }); +} + +CSSSelector * submitSelector() +{ + return namedBlockSelector(@":submit", ^BOOL(HTMLElement * _Nonnull element) { + if ([element.tagName isEqualToString:@"input"] && [element[@"type"] isEqualToString:@"submit"]) { + return YES; + } + if ([element.tagName isEqualToString:@"button"] && [element[@"type"] isEqualToString:@"submit"]) { + return YES; + } + return NO; + }); +} + +CSSSelector * textSelector() +{ + return namedBlockSelector(@":text", ^BOOL(HTMLElement * _Nonnull element) { + if ([element[@"type"] isEqualToString:@"text"]) { + return YES; + } + return NO; + }); +} + +#pragma mark - State + +CSSSelector * enabledSelector() +{ + // https://html.spec.whatwg.org/multipage/scripting.html#selector-enabled + CSSSelector *candiate = anyOf(@[ + typeSelector(@"button"), + typeSelector(@"input"), + typeSelector(@"select"), + typeSelector(@"textarea"), + typeSelector(@"optgroup"), + typeSelector(@"option"), + typeSelector(@"menuitem"), + typeSelector(@"fieldset"), + ]); + return namedPseudoSelector(@"enabled", allOf(@[candiate, not(disabledSelector())])); +} + +CSSSelector * disabledSelector() +{ + // https://html.spec.whatwg.org/multipage/scripting.html#selector-disabled + CSSSelector *disabledAttribute = hasAttributeSelector(@"disabled"); + + // https://html.spec.whatwg.org/multipage/forms.html#concept-fieldset-disabled + CSSSelector *disabledFieldset = allOf(@[typeSelector(@"fieldset"), disabledAttribute]); + CSSSelector *firstLegend = allOf(@[typeSelector(@"legend"), firstOfTypeSelector()]); + CSSSelector *firstLegendDecendantDisabledFieldSet = allOf(@[firstLegend, descendantOfElementSelector(disabledFieldset)]); + + // https://html.spec.whatwg.org/multipage/forms.html#concept-fe-disabled + CSSSelector *disabledForm = anyOf(@[ + anyOf(@[ + allOf(@[typeSelector(@"button"), disabledAttribute]), + allOf(@[typeSelector(@"input"), disabledAttribute]), + allOf(@[typeSelector(@"select"), disabledAttribute]), + allOf(@[typeSelector(@"textarea"), disabledAttribute]) + ]), + allOf(@[ + descendantOfElementSelector(disabledFieldset), + not(firstLegendDecendantDisabledFieldSet) + ]) + ]); + + // https://html.spec.whatwg.org/multipage/scripting.html#selector-disabled + CSSSelector *disabledMenuItem = allOf(@[typeSelector(@"menuitem"), disabledAttribute]); + CSSSelector *disabledOptgroup = allOf(@[typeSelector(@"optgroup"), disabledAttribute]); + + // https://html.spec.whatwg.org/multipage/forms.html#concept-option-disabled + CSSSelector *disabledOption = allOf(@[ + typeSelector(@"option"), + anyOf(@[ + disabledAttribute, + descendantOfElementSelector(disabledOptgroup)]) + ]); + return namedPseudoSelector(@"disabled", + anyOf(@[disabledOption, disabledOptgroup, disabledMenuItem, disabledForm, disabledFieldset])); +} + +CSSSelector * checkedSelector() +{ + // https://html.spec.whatwg.org/multipage/scripting.html#selector-checked + CSSSelector *candidate = anyOf(@[ + typeSelector(@"input"), + typeSelector(@"option"), + typeSelector(@"menutitem") + ]); + CSSSelector *hasAttribute = anyOf(@[ + hasAttributeSelector(@"checked"), + hasAttributeSelector(@"selected") + ]); + + return namedPseudoSelector(@"checked", allOf(@[candidate, hasAttribute])); +} + +CSSSelector * optionalSelector() +{ + // https://html.spec.whatwg.org/multipage/scripting.html#selector-optional + CSSSelector *candidate = anyOf(@[ + typeSelector(@"input"), + typeSelector(@"select"), + typeSelector(@"textarea") + ]); + CSSSelector *noAttribute = not(hasAttributeSelector(@"required")); + + return namedPseudoSelector(@"optional", allOf(@[candidate, noAttribute])); +} + +CSSSelector * requiredSelector() +{ + // https://html.spec.whatwg.org/multipage/scripting.html#selector-required + // https://html.spec.whatwg.org/multipage/forms.html#concept-input-required + CSSSelector *candidate = anyOf(@[ + typeSelector(@"input"), + typeSelector(@"select"), + typeSelector(@"textarea") + ]); + CSSSelector *hasAttribute = hasAttributeSelector(@"required"); + + return namedPseudoSelector(@"required", allOf(@[candidate, hasAttribute])); +} + +#pragma mark - Positional + +CSSSelector * ltSelector(NSInteger index) +{ + NSString *name = [NSString stringWithFormat:@":lt(%ld)", (long)index]; + return namedBlockSelector(name, ^BOOL(HTMLElement * _Nonnull element) { + NSUInteger elementIndex = [element.parentElement indexOfChildNode:element]; + + if (index > 0) { + return elementIndex < index; + } else { + return elementIndex < element.parentElement.childNodesCount - index - 1; + } + }); +} + +CSSSelector * gtSelector(NSInteger index) +{ + NSString *name = [NSString stringWithFormat:@":gt(%ld)", (long)index]; + return namedBlockSelector(name, ^BOOL(HTMLElement * _Nonnull element) { + NSUInteger elementIndex = [element.parentElement indexOfChildNode:element]; + + if (index > 0) { + return elementIndex > index; + } else { + return elementIndex > element.parentElement.childNodesCount - index - 1; + } + }); +} + +CSSSelector * eqSelector(NSInteger index) +{ + NSString *name = [NSString stringWithFormat:@":eq(%ld)", (long)index]; + return namedBlockSelector(name, ^BOOL(HTMLElement * _Nonnull element) { + NSUInteger elementIndex = [element.parentElement indexOfChildNode:element]; + + if (index > 0) { + return elementIndex == index; + } else { + return elementIndex == element.parentElement.childNodesCount - index - 1; + } + }); +} diff --git a/source/SketchPlugin/HTML/Sources/CSSTypeSelector.m b/source/SketchPlugin/HTML/Sources/CSSTypeSelector.m new file mode 100755 index 0000000..053ec74 --- /dev/null +++ b/source/SketchPlugin/HTML/Sources/CSSTypeSelector.m @@ -0,0 +1,50 @@ +// +// CSSTypeSelector.m +// HTMLKit +// +// Created by Iska on 13/05/15. +// Copyright (c) 2015 BrainCookie. All rights reserved. +// + +#import "CSSTypeSelector.h" +#import "HTMLElement.h" +#import "NSString+HTMLKit.h" + +@interface CSSTypeSelector () +{ + NSString *_type; +} +@end + +@implementation CSSTypeSelector + ++ (instancetype)universalSelector +{ + return [[self alloc] initWithType:@"*"]; +} + +- (instancetype)initWithType:(NSString *)type +{ + self = [super init]; + if (self) { + _type = [type copy]; + } + return self; +} + +- (BOOL)acceptElement:(HTMLElement *)element +{ + if ([_type isEqualToString:@"*"] || [_type isEqualToStringIgnoringCase:element.tagName]) { + return YES; + } + return NO; +} + +#pragma mark - Description + +- (NSString *)debugDescription +{ + return self.type; +} + +@end diff --git a/source/SketchPlugin/HTML/Sources/HTMLCharacterData.m b/source/SketchPlugin/HTML/Sources/HTMLCharacterData.m new file mode 100755 index 0000000..46615ca --- /dev/null +++ b/source/SketchPlugin/HTML/Sources/HTMLCharacterData.m @@ -0,0 +1,114 @@ +// +// HTMLCharacterData.m +// HTMLKit +// +// Created by Iska on 26/11/16. +// Copyright © 2016 BrainCookie. All rights reserved. +// + +#import "HTMLCharacterData.h" +#import "HTMLNode+Private.h" +#import "HTMLDocument+Private.h" +#import "HTMLKitDOMExceptions.h" + +@interface HTMLCharacterData () +{ + NSMutableString *_data; +} +@end + +@implementation HTMLCharacterData +@synthesize data = _data; + +- (instancetype)initWithName:(NSString *)name type:(HTMLNodeType)type data:(NSString *)data +{ + self = [super initWithName:name type:type]; + if (self) { + if (data) { + _data = [[NSMutableString alloc] initWithString:data]; + } + } + return self; +} + +- (NSString *)data +{ + if (_data == nil) { + _data = [[NSMutableString alloc] initWithString:@""]; + } + + return _data; +} + +- (NSString *)textContent +{ + return [self.data copy]; +} + +- (void)setTextContent:(NSString *)textContent +{ + [self setData:textContent]; +} + +- (NSUInteger)length +{ + return self.data.length; +} + +#pragma mark - Data + +NS_INLINE void CheckValidOffset(HTMLCharacterData *node, NSUInteger offset, NSString *cmd) +{ + if (offset > node.length) { + [NSException raise:HTMLKitIndexSizeError + format:@"%@: Index Size Error, invalid index %lu for character data node %@.", + cmd, (unsigned long)offset, node]; + } +} + +- (void)setData:(NSString *)data +{ + [self replaceDataInRange:NSMakeRange(0, self.length) withData:data]; +} + +- (void)appendData:(NSString *)data +{ + [self replaceDataInRange:NSMakeRange(self.length, 0) withData:data]; +} + +- (void)insertData:(NSString *)data atOffset:(NSUInteger)offset +{ + [self replaceDataInRange:NSMakeRange(offset, 0) withData:data]; +} + +- (void)deleteDataInRange:(NSRange)range +{ + [self replaceDataInRange:range withData:@""]; +} + +- (void)replaceDataInRange:(NSRange)range withData:(NSString *)data +{ + CheckValidOffset(self, range.location, NSStringFromSelector(_cmd)); + + range.length = MIN(range.length, self.length - range.location); + + [(NSMutableString *)self.data replaceCharactersInRange:range withString:data]; + [self.ownerDocument didRemoveCharacterDataInNode:self atOffset:range.location withLength:range.length]; + [self.ownerDocument didAddCharacterDataToNode:self atOffset:range.location withLength:data.length]; +} + +- (NSString *)substringDataWithRange:(NSRange)range +{ + return [_data substringWithRange:range]; +} + +#pragma mark - NSCopying + +- (id)copyWithZone:(NSZone *)zone +{ + HTMLCharacterData *copy = [super copyWithZone:zone]; + copy->_data = [_data mutableCopy]; + return copy; +} + +@end diff --git a/source/SketchPlugin/HTML/Sources/HTMLCharacterToken.m b/source/SketchPlugin/HTML/Sources/HTMLCharacterToken.m new file mode 100755 index 0000000..f866509 --- /dev/null +++ b/source/SketchPlugin/HTML/Sources/HTMLCharacterToken.m @@ -0,0 +1,101 @@ +// +// HTMLCharacterToken.m +// HTMLKit +// +// Created by Iska on 23/10/14. +// Copyright (c) 2014 BrainCookie. All rights reserved. +// + +#import "HTMLCharacterToken.h" +#import "NSString+HTMLKit.h" + +@interface HTMLCharacterToken () +{ + NSMutableString *_characters; +} +@end + +@implementation HTMLCharacterToken + +- (instancetype)initWithString:(NSString *)string +{ + self = [super init]; + if (self) { + _characters = [string mutableCopy]; + } + return self; +} + +- (void)appendString:(NSString *)string +{ + if (_characters == nil) { + _characters = [NSMutableString new]; + } + [_characters appendString:string]; +} + +- (BOOL)isWhitespaceToken +{ + return [_characters isHTMLWhitespaceString]; +} + +- (BOOL)isEmpty +{ + return _characters.length == 0; +} + +- (void)retainLeadingWhitespace +{ + NSUInteger index = _characters.leadingHTMLWhitespaceLength; + if (index > 0) { + [_characters setString:[_characters substringToIndex:index]]; + } +} + +- (void)trimLeadingWhitespace +{ + NSUInteger index = _characters.leadingHTMLWhitespaceLength; + if (index > 0) { + [_characters setString:[_characters substringFromIndex:index]]; + } +} + +- (void)trimFormIndex:(NSUInteger)index +{ + [_characters setString:[_characters substringFromIndex:index]]; +} + +- (HTMLCharacterToken *)tokenBySplitingLeadingWhiteSpace +{ + NSUInteger index = _characters.leadingHTMLWhitespaceLength; + if (index > 0) { + NSString *leading = [_characters substringToIndex:index]; + [_characters setString:[_characters substringFromIndex:index]]; + return [[HTMLCharacterToken alloc] initWithString:leading]; + } + + return nil; +} + +#pragma mark - NSObject + +- (BOOL)isEqual:(id)other +{ + if ([other isKindOfClass:[self class]]) { + HTMLCharacterToken *token = (HTMLCharacterToken *)other; + return bothNilOrEqual(self.characters, token.characters); + } + return NO; +} + +- (NSUInteger)hash +{ + return self.characters.hash; +} + +- (NSString *)description +{ + return [NSString stringWithFormat:@"<%@: %p Characters='%@'>", self.class, self, _characters]; +} + +@end diff --git a/source/SketchPlugin/HTML/Sources/HTMLComment.m b/source/SketchPlugin/HTML/Sources/HTMLComment.m new file mode 100755 index 0000000..afebf89 --- /dev/null +++ b/source/SketchPlugin/HTML/Sources/HTMLComment.m @@ -0,0 +1,38 @@ +// +// HTMLComment.m +// HTMLKit +// +// Created by Iska on 25/02/15. +// Copyright (c) 2015 BrainCookie. All rights reserved. +// + +#import "HTMLComment.h" +#import "HTMLCharacterData+Private.h" + +@implementation HTMLComment + +- (instancetype)init +{ + return [self initWithData:@""]; +} + +- (instancetype)initWithData:(NSString *)data +{ + return [super initWithName:@"#comment" type:HTMLNodeComment data:data]; +} + +#pragma mark - Serialization + +- (NSString *)outerHTML +{ + return [NSString stringWithFormat:@"", self.data]; +} + +#pragma mark - Description + +- (NSString *)description +{ + return [NSString stringWithFormat:@"<%@: %p >", self.class, self, self.data]; +} + +@end diff --git a/source/SketchPlugin/HTML/Sources/HTMLCommentToken.m b/source/SketchPlugin/HTML/Sources/HTMLCommentToken.m new file mode 100755 index 0000000..4d71b33 --- /dev/null +++ b/source/SketchPlugin/HTML/Sources/HTMLCommentToken.m @@ -0,0 +1,59 @@ +// +// HTMLCommentToken.m +// HTMLKit +// +// Created by Iska on 23/10/14. +// Copyright (c) 2014 BrainCookie. All rights reserved. +// + +#import "HTMLCommentToken.h" + +@interface HTMLCommentToken () +{ + NSMutableString *_data; +} +@end + +@implementation HTMLCommentToken +@synthesize data = _data; + +- (instancetype)initWithData:(NSString *)data +{ + self = [super init]; + if (self) { + self.type = HTMLTokenTypeComment; + _data = [data mutableCopy]; + } + return self; +} + +- (void)appendStringToData:(NSString *)string +{ + if (_data == nil) { + _data = [NSMutableString new]; + } + [_data appendString:string]; +} + +#pragma mark - NSObject + +- (BOOL)isEqual:(id)other +{ + if ([other isKindOfClass:[self class]]) { + HTMLCommentToken *token = (HTMLCommentToken *)other; + return bothNilOrEqual(self.data, token.data); + } + return NO; +} + +- (NSUInteger)hash +{ + return self.data.hash; +} + +- (NSString *)description +{ + return [NSString stringWithFormat:@"<%@: %p Data='%@'>", self.class, self, _data]; +} + +@end diff --git a/source/SketchPlugin/HTML/Sources/HTMLDOCTYPEToken.m b/source/SketchPlugin/HTML/Sources/HTMLDOCTYPEToken.m new file mode 100755 index 0000000..ba98f79 --- /dev/null +++ b/source/SketchPlugin/HTML/Sources/HTMLDOCTYPEToken.m @@ -0,0 +1,84 @@ +// +// HTMLDOCTYPEToken.m +// HTMLKit +// +// Created by Iska on 23/10/14. +// Copyright (c) 2014 BrainCookie. All rights reserved. +// + +#import "HTMLDOCTYPEToken.h" + +@interface HTMLDOCTYPEToken () +{ + NSMutableString *_name; +} + +@end + +@implementation HTMLDOCTYPEToken +@synthesize name = _name; + +- (instancetype)init +{ + return [self initWithName:nil]; +} + +- (instancetype)initWithName:(NSString *)name +{ + self = [super init]; + if (self) { + self.type = HTMLTokenTypeDoctype; + _name = [name mutableCopy]; + } + return self; +} + +- (void)appendStringToName:(NSString *)string +{ + if (_name == nil) { + _name = [NSMutableString new]; + } + [_name appendString:string]; +} + +- (void)appendStringToPublicIdentifier:(NSString *)string +{ + if (_publicIdentifier == nil) { + _publicIdentifier = [NSMutableString new]; + } + [_publicIdentifier appendString:string]; +} + +- (void)appendStringToSystemIdentifier:(NSString *)string +{ + if (_systemIdentifier == nil) { + _systemIdentifier = [NSMutableString new]; + } + [_systemIdentifier appendString:string]; +} + +#pragma mark - NSObject + +- (BOOL)isEqual:(id)other +{ + if ([other isKindOfClass:[self class]]) { + HTMLDOCTYPEToken *token = (HTMLDOCTYPEToken *)other; + return (bothNilOrEqual(self.name, token.name) && + bothNilOrEqual(self.publicIdentifier, token.publicIdentifier) && + bothNilOrEqual(self.systemIdentifier, token.systemIdentifier) && + self.forceQuirks == token.forceQuirks); + } + return NO; +} + +- (NSUInteger)hash +{ + return self.name.hash + self.publicIdentifier.hash + self.systemIdentifier.hash; +} + +- (NSString *)description +{ + return [NSString stringWithFormat:@"<%@: %p Name='%@' Public='%@' System='%@' ForceQuirks='%@'>", self.class, self, _name, _publicIdentifier, _systemIdentifier, @(_forceQuirks)]; +} + +@end diff --git a/source/SketchPlugin/HTML/Sources/HTMLDOMTokenList.m b/source/SketchPlugin/HTML/Sources/HTMLDOMTokenList.m new file mode 100755 index 0000000..2ee110f --- /dev/null +++ b/source/SketchPlugin/HTML/Sources/HTMLDOMTokenList.m @@ -0,0 +1,109 @@ +// +// HTMLDOMTokenList.m +// HTMLKit +// +// Created by Iska on 30/11/15. +// Copyright © 2015 BrainCookie. All rights reserved. +// + +#import "HTMLDOMTokenList.h" +#import "HTMLElement.h" + +@interface HTMLDOMTokenList () +{ + HTMLElement *_element; + NSString *_attribute; + NSMutableOrderedSet *_tokens; +} +@end + +@implementation HTMLDOMTokenList +@synthesize element = _element; +@synthesize attribute = _attribute; + +#pragma mark - Init + +- (instancetype)initWithElement:(HTMLElement *)element attribute:(NSString *)attribute value:(NSString *)value +{ + self = [super init]; + if (self) { + _element = element; + _attribute = [attribute copy]; + _tokens = [NSMutableOrderedSet new]; + [self add:[value componentsSeparatedByString:@" "]]; + } + return self; +} + +#pragma mark - Access + +- (void)updateValue +{ + _element[_attribute] = self.stringify; +} + +- (NSUInteger)length +{ + return _tokens.count; +} + +- (BOOL)contains:(NSString *)token +{ + return [_tokens containsObject:token]; +} + +- (void)add:(NSArray *)tokens +{ + for (NSString *token in tokens) { + if (![token isEqualToString:@""]) { + [_tokens addObject:token]; + } + } + [self updateValue]; +} + +- (void)remove:(NSArray *)tokens +{ + for (NSString *token in tokens) { + [_tokens removeObject:token]; + } + [self updateValue]; +} + +- (BOOL)toggle:(NSString *)token +{ + if ([_tokens containsObject:token]) { + [_tokens removeObject:token]; + [self updateValue]; + return NO; + } else { + [_tokens addObject:token]; + [self updateValue]; + return YES; + } +} + +- (void)replaceToken:(NSString *)token withToken:(NSString *)newToken +{ + NSUInteger index = [_tokens indexOfObject:token]; + _tokens[index] = newToken; + [self updateValue]; +} + +- (NSString *)objectAtIndexedSubscript:(NSUInteger)index +{ + return _tokens[index]; +} + +- (void)setObject:(NSString *)obj atIndexedSubscript:(NSUInteger)index +{ + _tokens[index] = obj; + [self updateValue]; +} + +- (NSString *)stringify +{ + return [_tokens.array componentsJoinedByString:@" "]; +} + +@end diff --git a/source/SketchPlugin/HTML/Sources/HTMLDOMUtils.m b/source/SketchPlugin/HTML/Sources/HTMLDOMUtils.m new file mode 100755 index 0000000..efc2d82 --- /dev/null +++ b/source/SketchPlugin/HTML/Sources/HTMLDOMUtils.m @@ -0,0 +1,32 @@ +// +// HTMLDOMUtils.m +// HTMLKit +// +// Created by Iska on 03/12/16. +// Copyright © 2016 BrainCookie. All rights reserved. +// + +#import "HTMLDOMUtils.h" +#import "HTMLNode.h" + +extern HTMLNode * GetCommonAncestorContainer(HTMLNode *nodeA, HTMLNode *nodeB) +{ + for (HTMLNode *parentA = nodeA; parentA != nil; parentA = parentA.parentNode) { + for (HTMLNode *parentB = nodeB; parentB != nil; parentB = parentB.parentNode) { + if (parentA == parentB) { + return parentA; + } + } + } + + return nil; +} + +extern NSArray * GetAncestorNodes(HTMLNode *node) +{ + NSMutableArray *ancestors = [NSMutableArray array]; + for (HTMLNode *it = node; it; it = it.parentNode) { + [ancestors addObject:it]; + } + return ancestors; +} diff --git a/source/SketchPlugin/HTML/Sources/HTMLDocument.m b/source/SketchPlugin/HTML/Sources/HTMLDocument.m new file mode 100755 index 0000000..33e84d4 --- /dev/null +++ b/source/SketchPlugin/HTML/Sources/HTMLDocument.m @@ -0,0 +1,243 @@ +// +// HTMLDocument.m +// HTMLKit +// +// Created by Iska on 25/02/15. +// Copyright (c) 2015 BrainCookie. All rights reserved. +// + +#import "HTMLDocument.h" +#import "HTMLParser.h" +#import "HTMLNodeIterator.h" +#import "HTMLRange.h" +#import "HTMLCharacterData.h" +#import "HTMLText.h" +#import "HTMLKitDOMExceptions.h" +#import "HTMLNode+Private.h" +#import "HTMLNodeIterator+Private.h" +#import "HTMLRange+Private.h" + +@interface HTMLDocument () +{ + HTMLDocument *_inertTemplateDocument; + NSHashTable *_nodeIterators; + NSHashTable *_ranges; +} +@property (nonatomic, assign) HTMLDocumentReadyState readyState; +@end + +@implementation HTMLDocument + +#pragma mark - Init + ++ (instancetype)documentWithString:(NSString *)string +{ + HTMLParser *parser = [[HTMLParser alloc] initWithString:string]; + return [parser parseDocument]; +} + +- (instancetype)init +{ + self = [super initWithName:@"#document" type:HTMLNodeDocument]; + if (self) { + _readyState = HTMLDocumentLoading; + _nodeIterators = [[NSHashTable alloc] initWithOptions:NSHashTableWeakMemory capacity:10]; + _ranges = [[NSHashTable alloc] initWithOptions:NSHashTableWeakMemory capacity:10]; + } + return self; +} + +#pragma mark - Accessors + +- (void)setOwnerDocument:(HTMLDocument *)ownerDocument +{ + [self doesNotRecognizeSelector:_cmd]; +} + +- (void)setDocumentType:(HTMLDocumentType *)documentType +{ + if (documentType == nil) { + if (self.documentType != nil) { + [self removeChildNode:self.documentType]; + } + return; + } + + if (self.documentType != nil) { + [self replaceChildNode:self.documentType withNode:documentType]; + } else { + [self appendNode:documentType]; + } +} + +#pragma mark - + +- (HTMLElement *)rootElement +{ + for (HTMLNode *node = self.firstChild; node; node = node.nextSibling) { + if (node.nodeType == HTMLNodeElement) { + return node.asElement; + } + } + return nil; +} + +- (void)setRootElement:(HTMLElement *)rootElement +{ + [self replaceChildNode:self.rootElement withNode:rootElement]; +} + +- (HTMLElement *)documentElement +{ + for (HTMLNode *node in [self nodeIteratorWithShowOptions:HTMLNodeFilterShowElement filter:nil]) { + if ([node.asElement.tagName isEqualToString:@"html"]) { + return node.asElement; + } + } + return nil; +} + +- (void)setDocumentElement:(HTMLElement *)documentElement +{ + [self replaceChildNode:self.documentElement withNode:documentElement]; +} + +- (HTMLElement *)head +{ + for (HTMLNode *node in [self nodeIteratorWithShowOptions:HTMLNodeFilterShowElement filter:nil]) { + if ([node.asElement.tagName isEqualToString:@"head"]) { + return node.asElement; + } + } + return nil; +} + +- (void)setHead:(HTMLElement *)head +{ + [self replaceChildNode:self.head withNode:head]; +} + +- (HTMLElement *)body +{ + for (HTMLNode *node in [self nodeIteratorWithShowOptions:HTMLNodeFilterShowElement filter:nil]) { + if ([node.asElement.tagName isEqualToString:@"body"]) { + return node.asElement; + } + } + return nil; +} + +- (void)setBody:(HTMLElement *)body +{ + [self replaceChildNode:self.body withNode:body]; +} + +#pragma mark - Node Iterators + +- (void)attachNodeIterator:(HTMLNodeIterator *)iterator +{ + [_nodeIterators addObject:iterator]; +} + +- (void)detachNodeIterator:(HTMLNodeIterator *)iterator +{ + [_nodeIterators removeObject:iterator]; +} + +#pragma mark - Ranges + +- (void)attachRange:(HTMLRange *)range +{ + [_ranges addObject:range]; +} + +- (void)detachRange:(HTMLRange *)range +{ + [_ranges removeObject:range]; +} + +- (void)didRemoveCharacterDataInNode:(HTMLCharacterData *)node atOffset:(NSUInteger)offset withLength:(NSUInteger)length +{ + for (HTMLRange *range in _ranges) { + [range didRemoveCharacterDataInNode:node atOffset:offset withLength:length]; + } +} + +- (void)didAddCharacterDataToNode:(HTMLCharacterData *)node atOffset:(NSUInteger)offset withLength:(NSUInteger)length +{ + for (HTMLRange *range in _ranges) { + [range didAddCharacterDataToNode:node atOffset:offset withLength:length]; + } +} + +- (void)didInsertNewTextNode:(HTMLText *)newNode intoParent:(HTMLNode *)parent afterSplittingTextNode:(HTMLText *)node atOffset:(NSUInteger)offset +{ + for (HTMLRange *range in _ranges) { + [range didInsertNewTextNode:newNode intoParent:parent afterSplittingTextNode:node atOffset:offset]; + } +} + +- (void)clampRangesAfterSplittingTextNode:(HTMLText *)node atOffset:(NSUInteger)offset +{ + for (HTMLRange *range in _ranges) { + [range clampRangesAfterSplittingTextNode:node atOffset:offset]; + } +} + +#pragma mark - Mutation Callback + +- (void)runRemovingStepsForNode:(HTMLNode *)oldNode + withOldParent:(HTMLNode *)oldParent + andOldPreviousSibling:(HTMLNode *)oldPreviousSibling +{ + for (HTMLRange *range in _ranges) { + [range runRemovingStepsForNode:oldNode + withOldParent:oldParent + andOldPreviousSibling:oldPreviousSibling]; + } + + for (HTMLNodeIterator *iterator in _nodeIterators) { + [iterator runRemovingStepsForNode:oldNode + withOldParent:oldParent + andOldPreviousSibling:oldPreviousSibling]; + } +} + +#pragma mark - Mutation Algorithms + +- (HTMLNode *)adoptNode:(HTMLNode *)node +{ + if (node == nil) { + return nil; + } + + if (node.nodeType == HTMLNodeDocument) { + [NSException raise:HTMLKitNotSupportedError + format:@"%@: Not Fount Error, adopting a document node. The operation is not supported.", NSStringFromSelector(_cmd)]; + } + + [node.parentNode removeChildNode:node]; + node.ownerDocument = self; + return node; +} + +#pragma mark - Template + +- (HTMLDocument *)associatedInertTemplateDocument +{ + if (_inertTemplateDocument == nil) { + _inertTemplateDocument = [HTMLDocument new]; + _inertTemplateDocument.readyState = HTMLDocumentComplete; + } + + return _inertTemplateDocument; +} + +#pragma mark - Description + +- (id)debugQuickLookObject +{ + return [[NSAttributedString alloc] initWithString:self.innerHTML]; +} + +@end diff --git a/source/SketchPlugin/HTML/Sources/HTMLDocumentFragment.m b/source/SketchPlugin/HTML/Sources/HTMLDocumentFragment.m new file mode 100755 index 0000000..f99483b --- /dev/null +++ b/source/SketchPlugin/HTML/Sources/HTMLDocumentFragment.m @@ -0,0 +1,46 @@ +// +// HTMLDocumentFragment.m +// HTMLKit +// +// Created by Iska on 12/04/15. +// Copyright (c) 2015 BrainCookie. All rights reserved. +// + +#import "HTMLDocumentFragment.h" +#import "HTMLText.h" +#import "HTMLNode+Private.h" + +@implementation HTMLDocumentFragment + +- (instancetype)init +{ + return [self initWithDocument:nil]; +} + +- (instancetype)initWithDocument:(HTMLDocument *)document +{ + self = [super initWithName:@"#document-fragment" type:HTMLNodeDocumentFragment]; + if (self) { + self.ownerDocument = document; + } + return self; +} + +- (NSString *)textContent +{ + NSMutableString *content = [NSMutableString string]; + for (HTMLNode *node in self.nodeIterator) { + if (node.nodeType == HTMLNodeText) { + [content appendString:[(HTMLText *)node data]]; + } + } + return content; +} + +- (void)setTextContent:(NSString *)textContent +{ + HTMLText *node = [[HTMLText alloc] initWithData:textContent]; + [self replaceAllChildNodesWithNode:node]; +} + +@end diff --git a/source/SketchPlugin/HTML/Sources/HTMLDocumentType.m b/source/SketchPlugin/HTML/Sources/HTMLDocumentType.m new file mode 100755 index 0000000..0bff20c --- /dev/null +++ b/source/SketchPlugin/HTML/Sources/HTMLDocumentType.m @@ -0,0 +1,162 @@ +// +// HTMLDocumentType.m +// HTMLKit +// +// Created by Iska on 25/02/15. +// Copyright (c) 2015 BrainCookie. All rights reserved. +// + +#import "HTMLDocumentType.h" +#import "NSString+HTMLKit.h" +#import "HTMLNode+Private.h" + +NS_INLINE BOOL nilOrEqual(id first, id second) { + return (first == nil) || ([first isEqual:second]); +} + +@interface HTMLDocumentType () +{ + NSString *_publicIdentifier; + NSString *_systemIdentifier; +} +@end + +@implementation HTMLDocumentType + +- (instancetype)init +{ + return [self initWithName:@"html" publicIdentifier:nil systemIdentifier:nil]; +} + +- (instancetype)initWithName:(NSString *)name + publicIdentifier:(NSString *)publicIdentifier + systemIdentifier:(NSString *)systemIdentifier +{ + self = [super initWithName:name type:HTMLNodeDocumentType]; + if (self) { + _publicIdentifier = [publicIdentifier copy]; + _systemIdentifier = [systemIdentifier copy]; + } + return self; +} + +- (NSString *)publicIdentifier +{ + return _publicIdentifier ?: @""; +} + +- (NSString *)systemIdentifier +{ + return _systemIdentifier ?: @""; +} + +- (BOOL)isValid +{ + if (![self.name isEqualToString:@"html"]) { + return NO; + } + + if ([_publicIdentifier isEqualToString:@"-//W3C//DTD HTML 4.0//EN"] && + nilOrEqual(_systemIdentifier, @"http://www.w3.org/TR/REC-html40/strict.dtd")) { + return YES; + } + + if ([_publicIdentifier isEqualToString:@"-//W3C//DTD HTML 4.01//EN"] && + nilOrEqual(_systemIdentifier, @"http://www.w3.org/TR/html4/strict.dtd")) { + return YES; + } + + if ([_publicIdentifier isEqualToString:@"-//W3C//DTD XHTML 1.0 Strict//EN"] && + nilOrEqual(_systemIdentifier, @"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd")) { + return YES; + } + + if ([_publicIdentifier isEqualToString:@"-//W3C//DTD XHTML 1.1//EN"] && + nilOrEqual(_systemIdentifier, @"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd")) { + return YES; + } + + if (_publicIdentifier != nil) { + return NO; + } + + if (_systemIdentifier && ![_systemIdentifier isEqualToString:@"about:legacy-compat"]) { + return NO; + } + + return YES; +} + +- (HTMLQuirksMode)quirksMode +{ + if (![self.name isEqualToString:@"html"]) { + return HTMLQuirksModeQuirks; + } + + if ([_publicIdentifier isEqualToStringIgnoringCase:@"-//W3O//DTD W3 HTML Strict 3.0//EN//"] || + [_publicIdentifier isEqualToStringIgnoringCase:@"-/W3C/DTD HTML 4.0 Transitional/EN"] || + [_publicIdentifier isEqualToStringIgnoringCase:@"HTML"]) { + return HTMLQuirksModeQuirks; + } + + if ([_publicIdentifier isEqualToStringIgnoringCase:@"http://www.ibm.com/data/dtd/v11/ibmxhtml1-transitional.dtd"]) { + return HTMLQuirksModeQuirks; + } + + if (QuirksModePrefixMatch(_publicIdentifier)) { + return HTMLQuirksModeQuirks; + } + + if (_systemIdentifier == nil) { + if ([_publicIdentifier hasPrefixIgnoringCase:@"-//W3C//DTD HTML 4.01 Frameset//"] || + [_publicIdentifier hasPrefixIgnoringCase:@"-//W3C//DTD HTML 4.01 Transitional//"]) { + return HTMLQuirksModeQuirks; + } + } + + if ([_publicIdentifier hasPrefixIgnoringCase:@"-//W3C//DTD XHTML 1.0 Frameset//"] || + [_publicIdentifier hasPrefixIgnoringCase:@"-//W3C//DTD XHTML 1.0 Transitional//"]) { + return HTMLQuirksModeLimitedQuirks; + } + + if (_systemIdentifier != nil) { + if ([_publicIdentifier hasPrefixIgnoringCase:@"-//W3C//DTD HTML 4.01 Frameset//"] || + [_publicIdentifier hasPrefixIgnoringCase:@"-//W3C//DTD HTML 4.01 Transitional//"]) { + return HTMLQuirksModeLimitedQuirks; + } + } + + return HTMLQuirksModeNoQuirks; +} + +- (NSUInteger)length +{ + return 0; +} + +#pragma mark - NSCopying + +- (id)copyWithZone:(NSZone *)zone +{ + HTMLDocumentType *copy = [super copyWithZone:zone]; + copy->_publicIdentifier = [_publicIdentifier copy]; + copy->_systemIdentifier = [_systemIdentifier copy]; + return copy; +} + +#pragma mark - Serialization + +- (NSString *)outerHTML +{ + return [NSString stringWithFormat:@"", self.name]; +} + +#pragma mark - Description + +- (NSString *)description +{ + return [NSString stringWithFormat:@"<%@: %p >", + self.class, self, self.name, self.publicIdentifier, self.systemIdentifier]; +} + +@end diff --git a/source/SketchPlugin/HTML/Sources/HTMLEOFToken.m b/source/SketchPlugin/HTML/Sources/HTMLEOFToken.m new file mode 100755 index 0000000..ecb8132 --- /dev/null +++ b/source/SketchPlugin/HTML/Sources/HTMLEOFToken.m @@ -0,0 +1,37 @@ +// +// HTMLEOFToken.m +// HTMLKit +// +// Created by Iska on 15/03/15. +// Copyright (c) 2015 BrainCookie. All rights reserved. +// + +#import "HTMLEOFToken.h" + +@implementation HTMLEOFToken + ++ (instancetype)token +{ + static dispatch_once_t onceToken; + static HTMLEOFToken *singleton = nil; + dispatch_once(&onceToken, ^{ + singleton = [[self alloc] init]; + }); + return singleton; +} + +- (instancetype)init +{ + self = [super init]; + if (self) { + self.type = HTMLTokenTypeEOF; + } + return self; +} + +- (NSString *)description +{ + return [NSString stringWithFormat:@"<%@: %p EOF>", self.class, self]; +} + +@end diff --git a/source/SketchPlugin/HTML/Sources/HTMLElement.m b/source/SketchPlugin/HTML/Sources/HTMLElement.m new file mode 100755 index 0000000..f36bc02 --- /dev/null +++ b/source/SketchPlugin/HTML/Sources/HTMLElement.m @@ -0,0 +1,216 @@ +// +// HTMLElement.m +// HTMLKit +// +// Created by Iska on 05/10/14. +// Copyright (c) 2014 BrainCookie. All rights reserved. +// + +#import "HTMLElement.h" +#import "HTMLParser.h" +#import "HTMLDocument.h" +#import "HTMLText.h" +#import "HTMLDOMTokenList.h" +#import "HTMLOrderedDictionary.h" +#import "NSString+HTMLKit.h" +#import "HTMLNode+Private.h" + +@interface HTMLElement () +{ + HTMLOrderedDictionary *_attributes; +} +@end + +@implementation HTMLElement + +#pragma mark - Init + +- (instancetype)init +{ + return [self initWithTagName:@""]; +} + +- (instancetype)initWithTagName:(NSString *)tagName +{ + return [self initWithTagName:tagName attributes:nil]; +} + +- (instancetype)initWithTagName:(NSString *)tagName attributes:(NSDictionary *)attributes +{ + return [self initWithTagName:tagName namespace:HTMLNamespaceHTML attributes:attributes]; +} + +- (instancetype)initWithTagName:(NSString *)tagName namespace:(HTMLNamespace)htmlNamespace attributes:(NSDictionary *)attributes +{ + self = [super initWithName:tagName type:HTMLNodeElement]; + if (self) { + _tagName = [tagName copy]; + _attributes = nil; + if (attributes != nil) { + _attributes = [HTMLOrderedDictionary new]; + [_attributes addEntriesFromDictionary:attributes]; + } + _htmlNamespace = htmlNamespace; + } + return self; +} + +#pragma mark - Special Attributes + +- (NSMutableDictionary *)attributes +{ + if (_attributes == nil) { + _attributes = [HTMLOrderedDictionary new]; + } + + return _attributes; +} + +- (NSString *)elementId +{ + return self.attributes[@"id"] ?: @""; +} + +- (void)setElementId:(NSString *)elementId +{ + self.attributes[@"id"] = elementId; +} + +- (NSString *)className +{ + return self.attributes[@"class"] ?: @""; +} + +- (void)setClassName:(NSString *)className +{ + self.attributes[@"class"] = className; +} + +- (HTMLDOMTokenList *)classList +{ + return [[HTMLDOMTokenList alloc] initWithElement:self attribute:@"class" value:self.className]; +} + +#pragma mark - Attributes + +- (BOOL)hasAttribute:(NSString *)name +{ + return self.attributes[name] != nil; +} + +- (NSString *)objectForKeyedSubscript:(NSString *)name; +{ + return self.attributes[name]; +} + +- (void)setObject:(NSString *)value forKeyedSubscript:(NSString *)attribute +{ + self.attributes[attribute] = value; +} + +- (void)removeAttribute:(NSString *)name +{ + [self.attributes removeObjectForKey:name]; +} + +- (NSString *)textContent +{ + NSMutableString *content = [NSMutableString string]; + for (HTMLNode *node in self.nodeIterator) { + if (node.nodeType == HTMLNodeText) { + [content appendString:[(HTMLText *)node data]]; + } + } + return content; +} + +- (void)setTextContent:(NSString *)textContent +{ + HTMLText *node = [[HTMLText alloc] initWithData:textContent]; + [self replaceAllChildNodesWithNode:node]; +} + +- (void)setInnerHTML:(NSString *)innerHTML +{ + HTMLParser *parser = [[HTMLParser alloc] initWithString:innerHTML]; + NSArray *fragmentNodes = [parser parseFragmentWithContextElement:self]; + [self removeAllChildNodes]; + [self appendNodes:fragmentNodes]; +} + +#pragma mark - NSCopying + +- (id)copyWithZone:(NSZone *)zone +{ + HTMLElement *copy = [super copyWithZone:zone]; + copy->_tagName = [_tagName copy]; + copy->_attributes = [_attributes copy]; + copy->_htmlNamespace = _htmlNamespace; + return copy; +} + +#pragma mark - Serialization + +- (NSString *)outerHTML +{ + NSMutableString *result = [NSMutableString string]; + + [result appendFormat:@"<%@", self.tagName]; + [self.attributes enumerateKeysAndObjectsUsingBlock:^(NSString *key, NSString *value, BOOL *stop) { + NSRange range = NSMakeRange(0, value.length); + NSMutableString *escaped = [value mutableCopy]; + [escaped replaceOccurrencesOfString:@"&" withString:@"&" options:0 range:range]; + [escaped replaceOccurrencesOfString:@"\00A0" withString:@" " options:0 range:range]; + [escaped replaceOccurrencesOfString:@"\"" withString:@""" options:0 range:range]; + + [result appendFormat:@" %@=\"%@\"", key, escaped]; + }]; + + [result appendString:@">"]; + + if ([self.tagName isEqualToAny:@"area", @"base", @"basefont", @"bgsound", @"br", @"col", @"embed", + @"frame", @"hr", @"img", @"input", @"keygen", @"link", @"menuitem", @"meta", @"param", @"source", + @"track", @"wbr", nil]) { + return result; + } + + if ([self.tagName isEqualToAny:@"pre", @"textarea", @"listing", nil] && self.firstChild.nodeType == HTMLNodeText) { + HTMLText *textNode = (HTMLText *)self.firstChild; + if ([textNode.data hasPrefix:@"\n"]) { + [result appendString:@"\n"]; + } + } + [result appendString:self.innerHTML]; + [result appendFormat:@"", self.tagName]; + + return result; +} + +#pragma mark - Description + +- (NSString *)description +{ + NSMutableString *description = [NSMutableString stringWithFormat:@"<%@: %p <", self.class, self]; + + if (self.htmlNamespace == HTMLNamespaceMathML) { + [description appendString:@"math "]; + } else if (self.htmlNamespace == HTMLNamespaceSVG) { + [description appendString:@"svg "]; + } + + [description appendString:self.tagName]; + [self.attributes enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) { + [description appendFormat:@" %@=\"%@\"", key, obj]; + }]; + + [description appendString:@">>"]; + + return description; +} + +- (NSString *)debugDescription +{ + return self.description; +} + +@end diff --git a/source/SketchPlugin/HTML/Sources/HTMLInputStreamReader.m b/source/SketchPlugin/HTML/Sources/HTMLInputStreamReader.m new file mode 100755 index 0000000..a493331 --- /dev/null +++ b/source/SketchPlugin/HTML/Sources/HTMLInputStreamReader.m @@ -0,0 +1,278 @@ +// +// HTMLInputStreamReader.m +// HTMLKit +// +// Created by Iska on 15/09/14. +// Copyright (c) 2014 BrainCookie. All rights reserved. +// + +#import "HTMLInputStreamReader.h" +#import "HTMLTokenizerCharacters.h" +#import "NSCharacterSet+HTMLKit.h" + +#pragma mark - HTMLInputStreamReader + +@interface HTMLInputStreamReader () +{ + NSString *_string; + NSScanner *_scanner; + CFStringInlineBuffer _buffer; + NSUInteger _location; + NSUInteger _mark; + UTF32Char _currentInputCharacter; + NSUInteger _consume; + HTMLStreamReaderErrorCallback _errorCallback; + + BOOL _reconsume; +} +@end + +@implementation HTMLInputStreamReader +@synthesize string = _string; +@synthesize currentLocation = _location; +@synthesize errorCallback = _errorCallback; + +#pragma mark - Lifecycle + +- (id)initWithString:(NSString *)string +{ + self = [super init]; + if (self) { + _string = [string copy]; + _scanner = [[NSScanner alloc] initWithString:string]; + _scanner.charactersToBeSkipped = nil; + CFStringInitInlineBuffer((CFStringRef)_string, &_buffer, CFRangeMake(0, _string.length)); + } + return self; +} + +#pragma mark - Errors + +- (void)emitParseError:(NSString *)reason +{ + if (self.errorCallback) { + self.errorCallback(reason); + } +} + +#pragma mark - Stream Processing + +- (UTF32Char)currentInputCharacter +{ + return _currentInputCharacter; +} + +- (UTF32Char)nextInputCharacter +{ + if (_reconsume) { + return _currentInputCharacter; + } + + _consume = 0; + UTF32Char nextInputCharacter = CFStringGetCharacterFromInlineBuffer(&_buffer, _location); + + if (nextInputCharacter == 0 && _location >= _string.length) return EOF; + + _consume = 1; + if (nextInputCharacter == CARRIAGE_RETURN) { + UniChar next = CFStringGetCharacterFromInlineBuffer(&_buffer, _location + 1); + if (next == LINE_FEED) { + _consume = 2; + } + return LINE_FEED; + } + if (CFStringIsSurrogateLowCharacter(nextInputCharacter)) { + NSString *reason = [NSString stringWithFormat:@"Non-Unicode character found (an isolated low surrogate: 0x%X)", (unsigned int)nextInputCharacter]; + [self emitParseError:reason]; + return nextInputCharacter; + } + + if (CFStringIsSurrogateHighCharacter(nextInputCharacter)) { + UniChar surrogateLow = CFStringGetCharacterFromInlineBuffer(&_buffer, _location + 1); + if (CFStringIsSurrogateLowCharacter(surrogateLow) == NO) { + NSString *reason = [NSString stringWithFormat:@"Non-Unicode character found (an isolated high surrogate: 0x%X)", (unsigned int)nextInputCharacter]; + [self emitParseError:reason]; + return nextInputCharacter; + } + + _consume = 2; + nextInputCharacter = CFStringGetLongCharacterForSurrogatePair(nextInputCharacter, surrogateLow); + } + + if (isControlOrUndefinedCharacter(nextInputCharacter)) { + NSString *reason = [NSString stringWithFormat:@"A control/undefined character found: (0x%X)", (unsigned int)nextInputCharacter]; + [self emitParseError:reason]; + } + + return nextInputCharacter; +} + +- (UTF32Char)inputCharacterPointAtOffset:(NSUInteger)offset +{ + return CFStringGetCharacterFromInlineBuffer(&_buffer, _location + offset); +} + +- (UTF32Char)consumeNextInputCharacter +{ + if (_reconsume) { + _reconsume = NO; + return _currentInputCharacter; + } + + UTF32Char nextInputCharacter = [self nextInputCharacter]; + _location += _consume; + _scanner.scanLocation = _location; + _currentInputCharacter = nextInputCharacter; + return nextInputCharacter; +} + +- (BOOL)consumeCharacter:(UTF32Char)character +{ + UTF32Char nextInputCharacter = [self nextInputCharacter]; + if (nextInputCharacter == character) { + if (!_reconsume) { + _location += _consume; + _scanner.scanLocation = _location; + _currentInputCharacter = nextInputCharacter; + } + _reconsume = NO; + return YES; + } + return NO; +} + +- (BOOL)consumeNumber:(unsigned long long *)result +{ + unsigned long long scanned; + BOOL success = [_scanner scanUnsignedLongLong:&scanned]; + if (success == NO) return NO; + + *result = scanned; + _location = _scanner.scanLocation; + return success; +} + +- (BOOL)consumeDecimalNumber:(NSDecimal *)result +{ + NSDecimal scanned; + BOOL success = [_scanner scanDecimal:&scanned]; + if (success == NO) return NO; + + *result = scanned; + _location = _scanner.scanLocation; + return success; +} + +- (BOOL)consumeHexNumber:(unsigned long long *)result +{ + NSCharacterSet *set = [NSCharacterSet HTMLHexNumberCharacterSet]; + + NSString *string = nil; + BOOL success = [_scanner scanCharactersFromSet:set intoString:&string]; + if (success == NO) return NO; + + unsigned long long scanned = strtoull(string.UTF8String, NULL, 16); + *result = scanned; + _location = _scanner.scanLocation; + return success; +} + +- (BOOL)consumeString:(NSString *)string caseSensitive:(BOOL)caseSensitive +{ + _scanner.caseSensitive = caseSensitive; + BOOL success = [_scanner scanString:string intoString:nil]; + _location = _scanner.scanLocation; + return success; +} + +- (NSString *)consumeCharactersUpToCharactersInString:(NSString *)characters +{ + NSCharacterSet *set = [NSCharacterSet characterSetWithCharactersInString:characters]; + + NSMutableString *consumed = [NSMutableString string]; + + while (YES) { + UTF32Char nextCharacter = [self consumeNextInputCharacter]; + if ([set longCharacterIsMember:nextCharacter] || nextCharacter == EOF) { + break; + } + [consumed appendString:StringFromUTF32Char(nextCharacter)]; + } + [self unconsumeCurrentInputCharacter]; + + return consumed.length > 0 ? consumed : nil; +} + +- (NSString *)consumeCharactersUpToString:(NSString *)string +{ + NSString *consumed; + [_scanner scanUpToString:string intoString:&consumed]; + _location = _scanner.scanLocation; + consumed = [consumed stringByReplacingOccurrencesOfString:@"\r\n" withString:@"\r"]; + consumed = [consumed stringByReplacingOccurrencesOfString:@"\r" withString:@"\n"]; + return consumed; +} + +- (NSString *)consumeCharactersInString:(NSString *)characters +{ + NSCharacterSet *set = [NSCharacterSet characterSetWithCharactersInString:characters]; + + if (_reconsume) { + _scanner.scanLocation--; + } + + NSString *string = nil; + BOOL success = [_scanner scanCharactersFromSet:set intoString:&string]; + if (success == NO) { + _scanner.scanLocation++; + return nil; + } + + _reconsume = NO; + _location = _scanner.scanLocation; + return string; +} + +- (NSString *)consumeAlphanumericCharacters +{ + NSCharacterSet *set = [NSCharacterSet alphanumericCharacterSet]; + NSString *consumed = nil; + + [_scanner scanCharactersFromSet:set intoString:&consumed]; + _location = _scanner.scanLocation; + return consumed; +} + +- (void)reconsumeCurrentInputCharacter +{ + _reconsume = YES; +} + +- (void)unconsumeCurrentInputCharacter +{ + _location -= _consume; + _scanner.scanLocation = _location; + _consume = 0; +} + +- (void)markCurrentLocation +{ + _mark = _location; +} + +- (void)rewindToMarkedLocation +{ + _location = _mark; + _scanner.scanLocation = _mark; + _consume = 0; +} + +- (void)reset +{ + _mark = 0; + _location = 0; + _scanner.scanLocation = 0; + _consume = 0; +} + +@end diff --git a/source/SketchPlugin/HTML/Sources/HTMLKit-Info.plist b/source/SketchPlugin/HTML/Sources/HTMLKit-Info.plist new file mode 100755 index 0000000..7b6a588 --- /dev/null +++ b/source/SketchPlugin/HTML/Sources/HTMLKit-Info.plist @@ -0,0 +1,30 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIconFile + + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + FMWK + CFBundleShortVersionString + 2.0.6 + CFBundleSignature + ???? + CFBundleVersion + 1 + NSHumanReadableCopyright + Copyright © 2014 BrainCookie. All rights reserved. + NSPrincipalClass + + + diff --git a/source/SketchPlugin/HTML/Sources/HTMLKitDOMExceptions.m b/source/SketchPlugin/HTML/Sources/HTMLKitDOMExceptions.m new file mode 100755 index 0000000..d568734 --- /dev/null +++ b/source/SketchPlugin/HTML/Sources/HTMLKitDOMExceptions.m @@ -0,0 +1,20 @@ +// +// HTMLKitExceptions.m +// HTMLKit +// +// Created by Iska on 17/03/15. +// Copyright (c) 2015 BrainCookie. All rights reserved. +// + +#import +#import "HTMLKitDOMExceptions.h" + +NSString * const HTMLKitHierarchyRequestError = @"HierarchyRequestError"; +NSString * const HTMLKitNotFoundError = @"NotFoundError"; +NSString * const HTMLKitNotSupportedError = @"NotSupportedError"; +NSString * const HTMLKitSyntaxError = @"SyntaxError"; +NSString * const HTMLKitInvalidCharacterError = @"InvalidCharacterError"; +NSString * const HTMLKitInvalidNodeTypeError = @"InvalidNodeTypeError"; +NSString * const HTMLKitIndexSizeError = @"IndexSizeError"; +NSString * const HTMLKitWrongDocumentError = @"WrongDocumentError"; +NSString * const HTMLKitInvalidStateError = @"InvalidStateError"; diff --git a/source/SketchPlugin/HTML/Sources/HTMLListOfActiveFormattingElements.m b/source/SketchPlugin/HTML/Sources/HTMLListOfActiveFormattingElements.m new file mode 100755 index 0000000..665ce8f --- /dev/null +++ b/source/SketchPlugin/HTML/Sources/HTMLListOfActiveFormattingElements.m @@ -0,0 +1,158 @@ +// +// HTMLListOfActiveFormattingElements.m +// HTMLKit +// +// Created by Iska on 22/03/15. +// Copyright (c) 2015 BrainCookie. All rights reserved. +// + +#import "HTMLListOfActiveFormattingElements.h" +#import "HTMLMarker.h" + +@interface HTMLListOfActiveFormattingElements () +{ + NSMutableArray *_list; +} +@end + +@implementation HTMLListOfActiveFormattingElements + +- (instancetype)init +{ + self = [super init]; + if (self) { + _list = [NSMutableArray new]; + } + return self; +} + +#pragma mark - Access + +- (id)objectAtIndexedSubscript:(NSUInteger)index; +{ + return [_list objectAtIndex:index]; +} + +- (void)setObject:(id)obj atIndexedSubscript:(NSUInteger)idx +{ + [_list setObject:obj atIndexedSubscript:idx]; +} + +- (NSUInteger)indexOfElement:(id)node +{ + return [_list indexOfObject:node]; +} + +- (void)addElement:(HTMLElement *)element +{ + NSUInteger existing = 0; + for (HTMLElement *node in _list.reverseObjectEnumerator) { + if ([node isEqual:[HTMLMarker marker]]) { + break; + } + if (node.htmlNamespace == element.htmlNamespace && + [node.tagName isEqualToString:element.tagName] && + [node.attributes isEqual:element.attributes]) { + existing++; + } + if (existing == 3) { + [_list removeObject:node]; + break; + } + } + [_list addObject:element]; +} + +- (void)removeElement:(id)element +{ + [_list removeObject:element]; +} + +- (BOOL)containsElement:(id)element +{ + return [_list containsObject:element]; +} + +- (void)insertElement:(HTMLElement *)element atIndex:(NSUInteger)index +{ + if (index > _list.count) { + index = _list.count; + } + [_list insertObject:element atIndex:index]; +} + +- (void)replaceElementAtIndex:(NSUInteger)index withElement:(HTMLElement *)element +{ + [_list replaceObjectAtIndex:index withObject:element]; +} + +- (id)lastEntry +{ + return _list.lastObject; +} + +#pragma mark - Acrions + +- (void)addMarker +{ + [_list addObject:[HTMLMarker marker]]; +} + +- (void)clearUptoLastMarker +{ + while (_list.lastObject && _list.lastObject != [HTMLMarker marker]) { + [_list removeLastObject]; + } + [_list removeLastObject]; +} + +- (HTMLElement *)formattingElementWithTagName:(NSString *)tagName +{ + for (HTMLElement *element in _list.reverseObjectEnumerator) { + if ([element isEqual:[HTMLMarker marker]]) return nil; + if ([element.tagName isEqualToString:tagName]) { + return element; + } + } + return nil; +} + +#pragma mark - Count + +- (NSUInteger)count +{ + return _list.count; +} + +- (BOOL)isEmpty +{ + return _list.count == 0; +} + +#pragma mark - Enumeraiton + +- (NSEnumerator *)enumerator +{ + return _list.objectEnumerator; +} + +- (NSEnumerator *)reverseObjectEnumerator +{ + return _list.reverseObjectEnumerator; +} + +#pragma mark - NSFastEnumeration + +- (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState *)state objects:(id __unsafe_unretained [])buffer count:(NSUInteger)len +{ + return [_list countByEnumeratingWithState:state objects:buffer count:len]; +} + +#pragma mark - Description + +- (NSString *)description +{ + return _list.description; +} + +@end diff --git a/source/SketchPlugin/HTML/Sources/HTMLMarker.m b/source/SketchPlugin/HTML/Sources/HTMLMarker.m new file mode 100755 index 0000000..c76a655 --- /dev/null +++ b/source/SketchPlugin/HTML/Sources/HTMLMarker.m @@ -0,0 +1,23 @@ +// +// HTMLMarker.m +// HTMLKit +// +// Created by Iska on 02/03/15. +// Copyright (c) 2015 BrainCookie. All rights reserved. +// + +#import "HTMLMarker.h" + +@implementation HTMLMarker + ++ (instancetype)marker +{ + static dispatch_once_t onceToken; + static HTMLMarker *singleton = nil; + dispatch_once(&onceToken, ^{ + singleton = [[self alloc] init]; + }); + return singleton; +} + +@end diff --git a/source/SketchPlugin/HTML/Sources/HTMLNode.m b/source/SketchPlugin/HTML/Sources/HTMLNode.m new file mode 100755 index 0000000..be9bb9e --- /dev/null +++ b/source/SketchPlugin/HTML/Sources/HTMLNode.m @@ -0,0 +1,776 @@ +// +// HTMLNode.m +// HTMLKit +// +// Created by Iska on 24/02/15. +// Copyright (c) 2015 BrainCookie. All rights reserved. +// + +#import "HTMLNode.h" +#import "HTMLNode+Private.h" +#import "HTMLDocument.h" +#import "HTMLDocumentType.h" +#import "HTMLElement.h" +#import "HTMLText.h" +#import "HTMLComment.h" +#import "HTMLKitDOMExceptions.h" +#import "HTMLNodeFilter.h" +#import "CSSSelector.h" +#import "HTMLDocument+Private.h" +#import "HTMLDOMUtils.h" + +NSString * const ValidationNodePreInsertion = @"-ensurePreInsertionValidityOfNode:beforeChildNode:"; +NSString * const ValidationNodeReplacement = @"-ensureReplacementValidityOfChildNode:withNode:"; +NSString * const RemoveChildNode = @"-removeChildNode:"; + +@interface HTMLNode () +{ + NSMutableOrderedSet *_childNodes; +} +@end + +@implementation HTMLNode +@synthesize ownerDocument = _ownerDocument; + +#pragma mark - Init + +- (instancetype)initWithName:(NSString *)name type:(HTMLNodeType)type +{ + self = [super init]; + if (self) { + _name = name; + _nodeType = type; + _childNodes = nil; + } + return self; +} + +#pragma mark - Properties + +- (NSOrderedSet *)childNodes +{ + if (_childNodes == nil) { + _childNodes = [NSMutableOrderedSet new]; + } + + return _childNodes; +} + +- (HTMLDocument *)ownerDocument +{ + if (_nodeType == HTMLNodeDocument) { + return (HTMLDocument *)self; + } else { + return _ownerDocument; + } +} + +- (void)setOwnerDocument:(HTMLDocument *)ownerDocument +{ + _ownerDocument = ownerDocument; + for (HTMLNode *child in _childNodes) { + [child setOwnerDocument:ownerDocument]; + } +} + +- (HTMLNode *)rootNode +{ + return _parentNode == nil ? self : _parentNode.rootNode; +} + +- (void)setParentNode:(HTMLNode *)parentNode +{ + _parentNode = parentNode; +} + +- (HTMLElement *)parentElement +{ + return _parentNode.nodeType == HTMLNodeElement ? (HTMLElement *)_parentNode : nil; +} + +- (HTMLNode *)firstChild +{ + return _childNodes.firstObject; +} + +- (HTMLNode *)lastChild +{ + return _childNodes.lastObject; +} + +- (HTMLNode *)previousSibling +{ + NSUInteger index = [_parentNode indexOfChildNode:self]; + if (index <= 0) { + return nil; + } + return [_parentNode childNodeAtIndex:index - 1]; +} + +- (HTMLNode *)nextSibling +{ + NSUInteger index = [_parentNode indexOfChildNode:self]; + if (index >= _parentNode.childNodesCount - 1) { + return nil; + } + return [_parentNode childNodeAtIndex:index + 1]; +} + +- (HTMLElement *)previousSiblingElement +{ + HTMLNode *node = self.previousSibling; + while (node && node.nodeType != HTMLNodeElement) { + node = node.previousSibling; + } + return node.asElement; +} + +- (HTMLElement *)nextSiblingElement +{ + HTMLNode *node = self.previousSibling; + while (node && node.nodeType != HTMLNodeElement) { + node = node.nextSibling; + } + return node.asElement; +} + +- (NSUInteger)index +{ + return [_parentNode indexOfChildNode:self]; +} + +- (NSString *)textContent +{ + return nil; +} + +- (NSUInteger)length +{ + return self.childNodesCount; +} + +#pragma mark - Cast + +- (HTMLElement *)asElement +{ + return (HTMLElement *)self; +} + +#pragma mark - Child Nodes + +- (BOOL)hasChildNodes +{ + return _childNodes.count > 0; +} + +- (BOOL)hasChildNodeOfType:(HTMLNodeType)type +{ + if (_childNodes == nil) { + return NO; + } + + NSUInteger index = [_childNodes indexOfObjectPassingTest:^BOOL(id obj, NSUInteger idx, BOOL *stop) { + if ([(HTMLNode *)obj nodeType] == type) { + *stop = YES; + return YES; + } + return NO; + }]; + + return index != NSNotFound; +} + +- (NSUInteger)childNodesCount +{ + return _childNodes.count; +} + +- (BOOL)isEmpty +{ + return self.length == 0; +} + +- (HTMLNode *)childNodeAtIndex:(NSUInteger)index +{ + return [_childNodes objectAtIndex:index]; +} + +- (NSUInteger)childElementsCount +{ + return [_childNodes indexesOfObjectsPassingTest:^BOOL(HTMLNode * _Nonnull node, NSUInteger idx, BOOL * _Nonnull stop) { + return node.nodeType == HTMLNodeElement; + }].count; +} + +- (NSUInteger)indexOfChildNode:(HTMLNode *)node +{ + return [_childNodes indexOfObject:node]; +} + +- (HTMLElement *)childElementAtIndex:(NSUInteger)index +{ + NSUInteger counter = 0; + for (HTMLNode *node in _childNodes) { + if (node.nodeType == HTMLNodeElement) { + if (counter == index) { + return node.asElement; + } + counter++; + } + } + return nil; +} + +- (NSUInteger)indexOfChildElement:(HTMLElement *)element +{ + NSUInteger counter = 0; + for (HTMLNode *node in _childNodes) { + if (node.nodeType == HTMLNodeElement) { + if (node == element) { + return counter; + } + counter++; + } + } + return NSNotFound; +} + +- (HTMLNode *)prependNode:(HTMLNode *)node +{ + return [self insertNode:node beforeChildNode:self.firstChild]; +} + +- (void)prependNodes:(NSArray *)nodes +{ + for (id node in nodes.reverseObjectEnumerator) { + [self insertNode:node beforeChildNode:self.firstChild]; + } +} + +- (HTMLNode *)appendNode:(HTMLNode *)node +{ + return [self insertNode:node beforeChildNode:nil]; +} + +- (void)appendNodes:(NSArray *)nodes +{ + for (id node in nodes) { + [self insertNode:node beforeChildNode:nil]; + } +} + +- (HTMLNode *)insertNode:(HTMLNode *)node beforeChildNode:(HTMLNode *)child +{ +#ifndef HTMLKIT_NO_DOM_CHECKS + [self ensurePreInsertionValidityOfNode:node beforeChildNode:child]; +#endif + + [self.ownerDocument adoptNode:node]; + + NSArray *nodes = node.nodeType == HTMLNodeDocumentFragment ? [NSArray arrayWithArray:node.childNodes.array] : @[node]; + + NSUInteger index = [self indexOfChildNode:child]; + if (index != NSNotFound) { + NSIndexSet *indexes = [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(index, nodes.count)]; + [(NSMutableOrderedSet *)self.childNodes insertObjects:nodes atIndexes:indexes]; + } else { + [(NSMutableOrderedSet *)self.childNodes addObjectsFromArray:nodes]; + } + + if (node.nodeType == HTMLNodeDocumentFragment) { + [node removeAllChildNodes]; + } + + for (HTMLNode *node in nodes) { + [node setParentNode:self]; + } + + return node; +} + +- (HTMLNode *)replaceChildNode:(HTMLNode *)child withNode:(HTMLNode *)node +{ +#ifndef HTMLKIT_NO_DOM_CHECKS + [self ensureReplacementValidityOfChildNode:child withNode:node]; +#endif + + [self insertNode:node beforeChildNode:child]; + [child removeFromParentNode]; + return child; +} + +- (void)replaceAllChildNodesWithNode:(HTMLNode *)node +{ + [self removeAllChildNodes]; + + if (node != nil) { + [self.ownerDocument adoptNode:node]; + [self insertNode:node beforeChildNode:nil]; + } +} + +- (void)removeFromParentNode +{ + [_parentNode removeChildNode:self]; +} + +- (HTMLNode *)removeChildNode:(HTMLNode *)child +{ + if (child.parentNode != self) { + [NSException raise:HTMLKitNotFoundError + format:@"%@: Not Fount Error, removing non-child node %@. The object can not be found here.", + RemoveChildNode, child]; + } + + HTMLNode *oldNode = child; + HTMLNode *oldParent = child.parentNode; + HTMLNode *oldPreviousSibling = child.previousSibling; + + [(NSMutableOrderedSet *)self.childNodes removeObject:child]; + child.parentNode = nil; + + [self.ownerDocument runRemovingStepsForNode:oldNode + withOldParent:oldParent + andOldPreviousSibling:oldPreviousSibling]; + return child; +} + +- (HTMLNode *)removeChildNodeAtIndex:(NSUInteger)index +{ + HTMLNode *node = [self childNodeAtIndex:index]; + return [self removeChildNode:node]; +} + +- (void)reparentChildNodesIntoNode:(HTMLNode *)node +{ + for (HTMLNode *child in _childNodes) { + [node appendNode:child]; + } + [(NSMutableOrderedSet *)_childNodes removeAllObjects]; +} + +- (void)removeAllChildNodes +{ + for (HTMLNode *child in _childNodes) { + [child setParentNode:nil]; + } + [(NSMutableOrderedSet *)_childNodes removeAllObjects]; +} + +- (HTMLDocumentPosition)compareDocumentPositionWithNode:(HTMLNode *)otherNode +{ + if (otherNode == nil) { + return HTMLDocumentPositionDisconnected; + } + + if (self == otherNode) { + return HTMLDocumentPositionEquivalent; + } + + if (self.ownerDocument != otherNode.ownerDocument) { + return (HTMLDocumentPositionDisconnected | HTMLDocumentPositionImplementationSpecific | + self.hash < otherNode.hash ? HTMLDocumentPositionPreceding : HTMLDocumentPositionFollowing); + } + + NSArray *ancestors1 = GetAncestorNodes(self); + NSArray *ancestors2 = GetAncestorNodes(otherNode); + + if (ancestors1.lastObject != ancestors2.lastObject) { + return (HTMLDocumentPositionDisconnected | HTMLDocumentPositionImplementationSpecific | + self.hash < otherNode.hash ? HTMLDocumentPositionPreceding : HTMLDocumentPositionFollowing); + } + + NSUInteger index1 = ancestors1.count; + NSUInteger index2 = ancestors2.count; + + for (NSUInteger i = MIN(index1, index2); i; --i) { + index1 -= 1; + index2 -= 1; + + HTMLNode *child1 = ancestors1[index1]; + HTMLNode *child2 = ancestors2[index2]; + + if (child1 != child2) { + for (HTMLNode *sibling = child1.nextSibling; sibling; sibling = sibling.nextSibling) { + if (sibling == child2) { + return HTMLDocumentPositionPreceding; + } + } + return HTMLDocumentPositionFollowing; + } + } + + if (ancestors1.count < ancestors2.count) { + return HTMLDocumentPositionContains | HTMLDocumentPositionPreceding; + } else { + return HTMLDocumentPositionContainedBy | HTMLDocumentPositionFollowing; + } +} + +- (BOOL)isDescendantOfNode:(HTMLNode *)otherNode +{ + if (otherNode == nil) { + return NO; + } + + if (self.ownerDocument != otherNode.ownerDocument) { + return NO; + } + + if (!otherNode.hasChildNodes) { + return NO; + } + + if (otherNode.nodeType == HTMLNodeDocument) { + return self.nodeType != HTMLNodeDocument && self.ownerDocument == otherNode; + } + + for (HTMLNode *parentNode = _parentNode; parentNode; parentNode = parentNode.parentNode) { + if (parentNode == otherNode) { + return YES; + } + } + + return NO; +} + +- (BOOL)containsNode:(HTMLNode *)otherNode +{ + return self == otherNode || [otherNode isDescendantOfNode:self]; +} + +#pragma mark - Enumeration + +- (void)enumerateChildNodesUsingBlock:(void (^)(HTMLNode *node, NSUInteger idx, BOOL *stop))block +{ + if (block == nil) { + return; + } + + [_childNodes enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { + block(obj, idx, stop); + }]; +} + +- (void)enumerateChildElementsUsingBlock:(void (^)(HTMLElement *element, NSUInteger idx, BOOL *stop))block +{ + if (block == nil) { + return; + } + + [_childNodes enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { + if ([obj isKindOfClass:[HTMLElement class]]) { + block([obj asElement], idx, stop); + } + }]; +} + +- (HTMLNodeIterator *)nodeIterator +{ + return [self nodeIteratorWithShowOptions:HTMLNodeFilterShowAll filter:nil]; +} + +- (HTMLNodeIterator *)nodeIteratorWithShowOptions:(HTMLNodeFilterShowOptions)showOptions + filter:(id)filter +{ + return [[HTMLNodeIterator alloc] initWithNode:self showOptions:showOptions filter:filter]; +} + +- (HTMLNodeIterator *)nodeIteratorWithShowOptions:(HTMLNodeFilterShowOptions)showOptions + filterBlock:(HTMLNodeFilterValue (^)(HTMLNode *node))block +{ + HTMLNodeFilterBlock *filter = [HTMLNodeFilterBlock filterWithBlock:block]; + return [[HTMLNodeIterator alloc] initWithNode:self showOptions:showOptions filter:filter]; +} + +#pragma mark - Selectors + +- (HTMLElement *)querySelector:(NSString *)selectorString +{ + CSSSelector *selector = [CSSSelector selectorWithString:selectorString]; + return [self firstElementMatchingSelector:selector]; +} + +- (NSArray *)querySelectorAll:(NSString *)selectorString +{ + CSSSelector *selector = [CSSSelector selectorWithString:selectorString]; + return [self elementsMatchingSelector:selector]; +} + +- (HTMLElement *)firstElementMatchingSelector:(CSSSelector *)selector +{ + if (selector == nil) { + return nil; + } + + for (HTMLElement *element in [self nodeIteratorWithShowOptions:HTMLNodeFilterShowElement filter:nil]) { + if ([selector acceptElement:element]) { + return element; + } + } + return nil; +} + +- (NSArray *)elementsMatchingSelector:(CSSSelector *)selector +{ + if (selector == nil) { + return @[]; + } + + NSMutableArray *result = [NSMutableArray array]; + for (HTMLElement *element in [self nodeIteratorWithShowOptions:HTMLNodeFilterShowElement filter:nil]) { + if ([selector acceptElement:element]) { + [result addObject:element]; + } + } + return result; +} + +#ifndef HTMLKIT_NO_DOM_CHECKS + +#pragma mark - Validity Checks + +NS_INLINE void CheckParentValid(HTMLNode *parent, NSString *cmd) +{ + if (parent.nodeType != HTMLNodeDocument && + parent.nodeType != HTMLNodeDocumentFragment && + parent.nodeType != HTMLNodeElement) { + [NSException raise:HTMLKitHierarchyRequestError + format:@"%@: Hierarchy Request Error, inserting into %@ is not allowed. The operation would yield an incorrect node tree.", + cmd, parent.name]; + } +} + +NS_INLINE void CheckChildsParent(HTMLNode *parent, HTMLNode *child, NSString *cmd) +{ + if (child != nil && + child.parentNode != parent) { + [NSException raise:HTMLKitNotFoundError + format:@"%@: Not Fount Error, insering before non-child node %@. The object can not be found here.", + cmd, child]; + } +} + +NS_INLINE void CheckInsertedNodeValid(HTMLNode *node, NSString *cmd) +{ + if (node.nodeType != HTMLNodeDocumentFragment && + node.nodeType != HTMLNodeDocumentType && + node.nodeType != HTMLNodeElement && + node.nodeType != HTMLNodeText && + node.nodeType != HTMLNodeComment) { + [NSException raise:HTMLKitHierarchyRequestError + format:@"%@: Hierarchy Request Error, inserting a %@ is not allowed. The operation would yield an incorrect node tree.", + cmd, node.name]; + } +} + +NS_INLINE void CheckInvalidCombination(HTMLNode *parent, HTMLNode *node, NSString *cmd) +{ + if (node.nodeType == HTMLNodeText && parent.nodeType == HTMLNodeDocument) { + [NSException raise:HTMLKitHierarchyRequestError + format:@"%@: Hierarchy Request Error, inserting a text node %@ into docuement is not allowed. The operation would yield an incorrect node tree.", + cmd, parent.name]; + } + + if (node.nodeType == HTMLNodeDocumentType && parent.nodeType != HTMLNodeDocument) { + [NSException raise:HTMLKitHierarchyRequestError + format:@"%@: Hierarchy Request Error, inserting a doctype %@ into a non-document node is not allowed. The operation would yield an incorrect node tree.", + cmd, parent.name]; + } +} + +- (void)ensurePreInsertionValidityOfNode:(HTMLNode *)node beforeChildNode:(HTMLNode *)child +{ + CheckParentValid(self, ValidationNodePreInsertion); + + CheckChildsParent(self, child, ValidationNodePreInsertion); + + CheckInsertedNodeValid(node, ValidationNodePreInsertion); + + CheckInvalidCombination(self, node, ValidationNodePreInsertion); + + void (^ hierarchyError)() = ^{ + [NSException raise:HTMLKitHierarchyRequestError + format:@"%@: Hierarchy Request Error, inserting (%@) into (%@). The operation would yield an incorrect node tree.", + ValidationNodePreInsertion, self, node]; + }; + + if (self.nodeType == HTMLNodeDocument) { + switch (node.nodeType) { + case HTMLNodeDocumentFragment: + if (node.childNodesCount > 1 || + [node hasChildNodeOfType:HTMLNodeText]) { + hierarchyError(); + } else if (node.childNodesCount == 1) { + if ([self hasChildNodeOfType:HTMLNodeElement] || + child.nodeType == HTMLNodeDocumentType || + child.nextSibling.nodeType == HTMLNodeDocumentType) { + hierarchyError(); + } + } + break; + case HTMLNodeElement: + if ([self hasChildNodeOfType:HTMLNodeElement] || + child.nodeType == HTMLNodeDocumentType || + (child != nil && child.nextSibling.nodeType == HTMLNodeDocumentType)) { + hierarchyError(); + } + break; + case HTMLNodeDocumentType: + if ([self hasChildNodeOfType:HTMLNodeDocumentType] || + child.previousSibling != nil || + (child == nil && [self hasChildNodeOfType:HTMLNodeElement])) { + hierarchyError(); + } + break; + default: + break; + } + } +} + +- (void)ensureReplacementValidityOfChildNode:(HTMLNode *)child withNode:(HTMLNode *)node +{ + CheckParentValid(self, ValidationNodeReplacement); + + CheckChildsParent(self, child, ValidationNodeReplacement); + + CheckInsertedNodeValid(node, ValidationNodeReplacement); + + CheckInvalidCombination(self, node, ValidationNodeReplacement); + + void (^ hierarchyError)() = ^{ + [NSException raise:HTMLKitHierarchyRequestError + format:@"%@: Hierarchy Request Error. The operation would yield an incorrect node tree.", + ValidationNodeReplacement]; + }; + + void (^ checkParentHasAnotherChildOfType)(HTMLNodeType) = ^ void (HTMLNodeType type) { + [self enumerateChildNodesUsingBlock:^(HTMLNode *node, NSUInteger idx, BOOL *stop) { + if (node.nodeType == type && node != child) { + *stop = YES; + hierarchyError(); + } + }]; + }; + + if (self.nodeType == HTMLNodeDocument) { + switch (node.nodeType) { + case HTMLNodeDocumentFragment: + if (node.childNodesCount > 1 || + [node hasChildNodeOfType:HTMLNodeText]) { + hierarchyError(); + } else if (node.childNodesCount == 1) { + if (child.nextSibling.nodeType == HTMLNodeDocumentType) { + hierarchyError(); + } + checkParentHasAnotherChildOfType(HTMLNodeElement); + } + break; + case HTMLNodeElement: + { + if (child.nextSibling.nodeType == HTMLNodeDocumentType) { + hierarchyError(); + } + checkParentHasAnotherChildOfType(HTMLNodeElement); + break; + } + case HTMLNodeDocumentType: + { + if (child.previousSibling.nodeType == HTMLNodeElement) { + hierarchyError(); + } + checkParentHasAnotherChildOfType(HTMLNodeDocumentType); + break; + } + default: + break; + } + } +} + +#endif + +#pragma mark - Clone + +- (instancetype)cloneNodeDeep:(BOOL)deep +{ + HTMLNode *copy = [self copy]; + + if (deep) { + for (HTMLNode *child in _childNodes) { + [copy appendNode:[child cloneNodeDeep:YES]]; + } + } + + return copy; +} + +#pragma mark - NSCopying + +- (id)copyWithZone:(NSZone *)zone +{ + HTMLNode *copy = [[self.class alloc] initWithName:self.name type:self.nodeType]; + return copy; +} + +#pragma mark - Serialization + +- (NSString *)outerHTML +{ + [self doesNotRecognizeSelector:_cmd]; + return nil; +} + +- (NSString *)innerHTML +{ + return [[self.childNodes.array valueForKey:@"outerHTML"] componentsJoinedByString:@""]; +} + +- (void)setInnerHTML:(NSString *)outerHTML +{ + [self doesNotRecognizeSelector:_cmd]; +} + +#pragma mark - Description + +- (NSString *)treeDescription +{ + NSMutableString *string = [NSMutableString string]; + + __weak __block void (^ weakAccumulator) (HTMLNode *, NSUInteger); + void (^ accumulator) (HTMLNode *, NSUInteger); + static NSString *prefix = @"| "; + + weakAccumulator = accumulator = ^ (HTMLNode *node, NSUInteger level) { + + NSString *indent = [prefix stringByPaddingToLength:level * 2 + prefix.length + withString:@" " + startingAtIndex:0]; + if (level > 0) { + [string appendString:@"\n"]; + } + + [string appendString:indent]; + [string appendString:node.description]; + + for (HTMLNode *child in node.childNodes) { + weakAccumulator(child, level + 1); + } + }; + accumulator(self, 0); + + return string; +} + +- (NSString *)description +{ + return [NSString stringWithFormat:@"<%@: %p '%@'>", self.class, self, self.name]; +} + +- (id)debugQuickLookObject +{ + return self.outerHTML; +} + +@end diff --git a/source/SketchPlugin/HTML/Sources/HTMLNodeFilter.m b/source/SketchPlugin/HTML/Sources/HTMLNodeFilter.m new file mode 100755 index 0000000..a6a6190 --- /dev/null +++ b/source/SketchPlugin/HTML/Sources/HTMLNodeFilter.m @@ -0,0 +1,86 @@ +// +// HTMLNodeFilter.m +// HTMLKit +// +// Created by Iska on 05/06/15. +// Copyright (c) 2015 BrainCookie. All rights reserved. +// + +#import "HTMLNodeFilter.h" +#import "HTMLNode.h" +#import "HTMLNode+Private.h" +#import "CSSSelector.h" + +#pragma mark - Block Filter + +@interface HTMLNodeFilterBlock () +{ + BOOL (^ _block)(HTMLNode *); +} +@end + +@implementation HTMLNodeFilterBlock + ++ (instancetype)filterWithBlock:(HTMLNodeFilterValue (^)(HTMLNode *))block +{ + return [[self alloc] initWithBlock:block]; +} + +- (instancetype)initWithBlock:(HTMLNodeFilterValue (^)(HTMLNode *))block +{ + self = [super init]; + if (self) { + _block = [block copy]; + } + return self; +} + +- (HTMLNodeFilterValue)acceptNode:(HTMLNode *)node +{ + if (!_block) { + return HTMLNodeFilterSkip; + } + + return _block(node); +} + +@end + +#pragma mark - CSS Selector Filter + +@interface HTMLSelectorNodeFilter () +{ + CSSSelector *_selector; +} +@end + +@implementation HTMLSelectorNodeFilter + ++ (instancetype)filterWithSelector:(CSSSelector *)selector +{ + return [[self alloc] initWithSelector:selector]; +} + +- (instancetype)initWithSelector:(CSSSelector *)selector +{ + self = [super init]; + if (self) { + _selector = selector; + } + return self; +} + +- (HTMLNodeFilterValue)acceptNode:(HTMLNode *)node +{ + if (node.nodeType != HTMLNodeElement) { + return HTMLNodeFilterSkip; + } + + if ([_selector acceptElement:node.asElement]) { + return HTMLNodeFilterAccept; + } + + return HTMLNodeFilterSkip; +} + +@end diff --git a/source/SketchPlugin/HTML/Sources/HTMLNodeIterator.m b/source/SketchPlugin/HTML/Sources/HTMLNodeIterator.m new file mode 100755 index 0000000..7c0937e --- /dev/null +++ b/source/SketchPlugin/HTML/Sources/HTMLNodeIterator.m @@ -0,0 +1,153 @@ +// +// HTMLNodeIterator.m +// HTMLKit +// +// Created by Iska on 27/05/15. +// Copyright (c) 2015 BrainCookie. All rights reserved. +// + +#import "HTMLNodeIterator.h" +#import "HTMLDocument.h" +#import "HTMLNode.h" +#import "HTMLNodeFilter.h" +#import "HTMLNodeTraversal.h" +#import "HTMLDocument+Private.h" + +typedef NS_ENUM(short, TraverseDirection) +{ + TraverseDirectionNext, + TraverseDirectionPrevious +}; + +@interface HTMLNodeIterator () +{ + HTMLNode *_root; +} +@end + +@implementation HTMLNodeIterator + +#pragma mark - Lifecycle + +- (instancetype)initWithNode:(HTMLNode *)node +{ + return [self initWithNode:node filter:nil]; +} + +- (instancetype)initWithNode:(HTMLNode *)node + filter:(id)filter +{ + return [self initWithNode:node showOptions:HTMLNodeFilterShowAll filter:filter]; +} + +- (instancetype)initWithNode:(HTMLNode *)node + showOptions:(HTMLNodeFilterShowOptions)showOptions + filter:(id)filter +{ + self = [super init]; + if (self) { + _root = node; + _filter = filter; + _whatToShow = showOptions; + _referenceNode = _root; + _pointerBeforeReferenceNode = YES; + [_root.ownerDocument attachNodeIterator:self]; + } + return self; +} + +- (void)dealloc +{ + [_root.ownerDocument detachNodeIterator:self]; +} + +#pragma mark - Removing Steps + +- (void)runRemovingStepsForNode:(HTMLNode *)oldNode + withOldParent:(HTMLNode *)oldParent + andOldPreviousSibling:(HTMLNode *)oldPreviousSibling +{ + if ([oldNode containsNode:_root]) { + return; + } + + if (![oldNode containsNode:_referenceNode]) { + return; + } + + if (_pointerBeforeReferenceNode) { + HTMLNode *nextSibling = oldPreviousSibling != nil ? oldPreviousSibling.nextSibling : oldParent.firstChild; + if (nextSibling != nil) { + _referenceNode = nextSibling; + return; + } + + HTMLNode *next = FollowingNode(oldParent, _root); + if ([_root containsNode:next]) { + _referenceNode = next; + return; + } + + _pointerBeforeReferenceNode = NO; + } + + HTMLNode * (^ lastInclusiveDescendant) (HTMLNode *) = ^ HTMLNode * (HTMLNode *node) { + while (node.lastChild) { + node = node.lastChild; + } + return node; + }; + + _referenceNode = oldPreviousSibling != nil ? lastInclusiveDescendant(oldPreviousSibling) : oldParent; +} + +#pragma mark - Traversal + +- (HTMLNode *)traverseInDirection:(TraverseDirection)direction +{ + HTMLNode *node = self.referenceNode; + BOOL beforeNode = self.pointerBeforeReferenceNode; + + do { + if (direction == TraverseDirectionNext) { + if (!beforeNode) { + node = FollowingNode(node, self.root); + if (node == nil) { + return nil; + } + } + beforeNode = NO; + } else { + if (beforeNode) { + node = PrecedingNode(node, self.root); + if (node == nil) { + return nil; + } + } + beforeNode = YES; + } + } while (FilterNode(self.filter, self.whatToShow, node) != HTMLNodeFilterAccept); + + _referenceNode = node; + _pointerBeforeReferenceNode = beforeNode; + return node; +} + +- (HTMLNode *)nextNode +{ + return [self traverseInDirection:TraverseDirectionNext]; +} + +- (HTMLNode *)previousNode +{ + return [self traverseInDirection:TraverseDirectionPrevious]; +} + +#pragma mark - NSEnumerator + +- (id)nextObject +{ + return self.nextNode; +} + +@end diff --git a/source/SketchPlugin/HTML/Sources/HTMLNodeTraversal.m b/source/SketchPlugin/HTML/Sources/HTMLNodeTraversal.m new file mode 100755 index 0000000..dd17b2a --- /dev/null +++ b/source/SketchPlugin/HTML/Sources/HTMLNodeTraversal.m @@ -0,0 +1,76 @@ +// +// HTMLNodeTraversal.m +// HTMLKit +// +// Created by Iska on 05/06/15. +// Copyright (c) 2015 BrainCookie. All rights reserved. +// + +#import "HTMLNodeTraversal.h" +#import "HTMLNode.h" +#import "HTMLNodeFilter.h" + +HTMLNode * PrecedingNode(HTMLNode *node, HTMLNode *root) +{ + HTMLNode *previous = node.previousSibling; + if (previous != nil) { + while (previous.lastChild != nil) { + previous = previous.lastChild; + } + return previous; + } + + if (node == root) { + return nil; + } + + return node.parentNode; +} + +HTMLNode * FollowingNode(HTMLNode *node, HTMLNode *root) +{ + if (node.firstChild != nil) { + return node.firstChild; + } + + do { + if (node == root) { + return nil; + } + if (node.nextSibling != nil) { + return node.nextSibling; + } + node = node.parentNode; + } while (node != nil); + + return nil; +} + +HTMLNode * FollowingNodeSkippingChildren(HTMLNode *node, HTMLNode *root) +{ + do { + if (node == root) { + return nil; + } + if (node.nextSibling != nil) { + return node.nextSibling; + } + node = node.parentNode; + } while (node != nil); + + return nil; +} + +HTMLNodeFilterValue FilterNode(id filter, HTMLNodeFilterShowOptions whatToShow, HTMLNode *node) +{ + unsigned long nthBit = (1 << (node.nodeType - 1)) & whatToShow; + if (!nthBit) { + return HTMLNodeFilterSkip; + } + + if (filter == nil) { + return HTMLNodeFilterAccept; + } + + return [filter acceptNode:node]; +} diff --git a/source/SketchPlugin/HTML/Sources/HTMLOrderedDictionary.m b/source/SketchPlugin/HTML/Sources/HTMLOrderedDictionary.m new file mode 100755 index 0000000..8cc03e5 --- /dev/null +++ b/source/SketchPlugin/HTML/Sources/HTMLOrderedDictionary.m @@ -0,0 +1,157 @@ +// +// HTMLOrderedDictionary.m +// HTMLKit +// +// Created by Iska on 14/03/15. +// Copyright (c) 2015 BrainCookie. All rights reserved. +// + +#import "HTMLOrderedDictionary.h" + +@interface HTMLOrderedDictionary () +{ + NSMutableDictionary *_dictionary; + NSMutableArray *_keys; +} +@end + +@implementation HTMLOrderedDictionary + +#pragma mark - Init + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wobjc-designated-initializers" +- (instancetype)init +{ + return [self initWithCapacity:0]; +} +#pragma clang diagnostic pop + +- (instancetype)initWithCapacity:(NSUInteger)capacity +{ + self = [super init]; + if (self) { + _dictionary = [[NSMutableDictionary alloc] initWithCapacity:capacity]; + _keys = [[NSMutableArray alloc] initWithCapacity:capacity]; + } + return self; +} + +- (instancetype)initWithObjects:(NSArray *)objects forKeys:(NSArray *)keys +{ + self = [self initWithCapacity:objects.count]; + if (self) { + [objects enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { + _dictionary[keys[idx]] = obj; + }]; + } + return self; +} + +#pragma mark - Access + +- (id)objectForKey:(id)aKey +{ + return _dictionary[aKey]; +} + +- (void)setObject:(id)anObject forKey:(id)aKey +{ + if (_dictionary[aKey] == nil) { + [_keys addObject:aKey]; + } + _dictionary[aKey] = anObject; +} + +- (void)removeObjectForKey:(id)aKey +{ + [_keys removeObject:aKey]; + [_dictionary removeObjectForKey:aKey]; +} + +- (NSUInteger)count +{ + return _keys.count; +} + +#pragma mark - Indexed Access + +- (id)objectAtIndex:(NSUInteger)index +{ + return _dictionary[_keys[index]]; +} + +- (void)setObject:(id)anObject forKey:(id)aKey atIndex:(NSUInteger)index +{ + if (_dictionary[aKey]) { + [_keys removeObject:aKey]; + } + [_keys insertObject:aKey atIndex:index]; + _dictionary[aKey] = anObject; +} + +- (void)removeObjectAtIndex:(NSUInteger)index +{ + if (_dictionary[_keys[index]]){ + [_dictionary removeObjectForKey:_keys[index]]; + [_keys removeObjectAtIndex:index]; + } +} + +- (void)replaceKeyValueAtIndex:(NSUInteger)index withObject:(id)anObject andKey:(id)aKey +{ + [_keys replaceObjectAtIndex:index withObject:aKey]; + _dictionary[aKey] = anObject; +} + +- (void)replaceKey:(id)aKey withKey:(id)newKey +{ + id value = _dictionary[aKey]; + if (value != nil) { + NSUInteger index = [_keys indexOfObject:aKey]; + [_keys replaceObjectAtIndex:index withObject:newKey]; + [_dictionary removeObjectForKey:aKey]; + _dictionary[newKey] = value; + } +} + +- (NSUInteger)indexOfKey:(id)aKey +{ + return [_keys indexOfObject:aKey]; +} + +#pragma mark - Subscript + +- (id)objectAtIndexedSubscript:(NSUInteger)index +{ + return _dictionary[_keys[index]]; +} + +- (void)setObject:(id)obj atIndexedSubscript:(NSUInteger)index +{ + _dictionary[_keys[index]] = obj; +} + +- (void)setObject:(id)obj forKeyedSubscript:(id)key +{ + [self setObject:obj forKey:key]; +} + +#pragma mark - Enumeration + +- (NSEnumerator *)keyEnumerator +{ + return _keys.objectEnumerator; +} + +- (NSEnumerator *)reverseKeyEnumerator +{ + return _keys.reverseObjectEnumerator; +} + +- (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState *)state objects:(__unsafe_unretained id [])buffer count:(NSUInteger)len +{ + return [_keys countByEnumeratingWithState:state objects:buffer count:len]; +} + +@end diff --git a/source/SketchPlugin/HTML/Sources/HTMLParseErrorToken.m b/source/SketchPlugin/HTML/Sources/HTMLParseErrorToken.m new file mode 100755 index 0000000..2072bca --- /dev/null +++ b/source/SketchPlugin/HTML/Sources/HTMLParseErrorToken.m @@ -0,0 +1,38 @@ +// +// HTMLParseErrorToken.m +// HTMLKit +// +// Created by Iska on 23/10/14. +// Copyright (c) 2014 BrainCookie. All rights reserved. +// + +#import "HTMLParseErrorToken.h" + +@interface HTMLParseErrorToken () +{ + NSString *_reason; + NSUInteger _location; +} +@end + +@implementation HTMLParseErrorToken +@synthesize reason = _reason; +@synthesize location = _location; + +- (instancetype)initWithReasonMessage:(NSString *)reason andStreamLocation:(NSUInteger)location +{ + self = [super init]; + if (self) { + self.type = HTMLTokenTypeParseError; + _reason = [reason copy]; + _location = location; + } + return self; +} + +- (NSString *)description +{ + return [NSString stringWithFormat:@"<%@: %p Reason='%@' Location='%lu'>", self.class, self, _reason, (unsigned long)_location]; +} + +@end diff --git a/source/SketchPlugin/HTML/Sources/HTMLParser.m b/source/SketchPlugin/HTML/Sources/HTMLParser.m new file mode 100755 index 0000000..2485650 --- /dev/null +++ b/source/SketchPlugin/HTML/Sources/HTMLParser.m @@ -0,0 +1,2610 @@ +// +// HTMLParser.m +// HTMLKit +// +// Created by Iska on 04/10/14. +// Copyright (c) 2014 BrainCookie. All rights reserved. +// + +#import "HTMLParser.h" +#import "HTMLTokenizer.h" +#import "HTMLTokens.h" +#import "HTMLStackOfOpenElements.h" +#import "HTMLListOfActiveFormattingElements.h" +#import "HTMLParserInsertionModes.h" +#import "HTMLDOM.h" +#import "HTMLElementTypes.h" +#import "HTMLElementAdjustment.h" +#import "HTMLMarker.h" +#import "NSString+HTMLKit.h" +#import "CSSSelectors.h" +#import "HTMLDocument+Private.h" + +@interface HTMLParser () +{ + HTMLTokenizer *_tokenizer; + + NSMutableArray *_errors; + + HTMLInsertionMode _insertionMode; + HTMLInsertionMode _originalInsertionMode; + NSMutableArray *_stackOfTemplateInsertionModes; + + HTMLStackOfOpenElements *_stackOfOpenElements; + HTMLListOfActiveFormattingElements *_listOfActiveFormattingElements; + + HTMLDocument *_document; + + HTMLElement *_contextElement; + HTMLElement *_currentElement; + + HTMLElement *_headElementPointer; + HTMLElement *_formElementPointer; + + HTMLCharacterToken *_pendingTableCharacterTokens; + + BOOL _framesetOkFlag; + BOOL _fragmentParsingAlgorithm; + BOOL _fosterParenting; + BOOL _ignoreNextLineFeedCharacterToken; +} +@end + +@implementation HTMLParser + +#pragma mark - Lifecycle + +- (instancetype)initWithString:(NSString *)string +{ + self = [super init]; + if (self) { + _framesetOkFlag = YES; + _fragmentParsingAlgorithm = NO; + _fosterParenting = NO; + _ignoreNextLineFeedCharacterToken = NO; + + _errors = [NSMutableArray new]; + + _insertionMode = HTMLInsertionModeInitial; + _stackOfTemplateInsertionModes = [NSMutableArray new]; + + _stackOfOpenElements = [HTMLStackOfOpenElements new]; + _listOfActiveFormattingElements = [HTMLListOfActiveFormattingElements new]; + + _tokenizer = [[HTMLTokenizer alloc] initWithString:string ?: @""]; + _tokenizer.parser = self; + + _pendingTableCharacterTokens = [[HTMLCharacterToken alloc] initWithString:@""]; + + _headElementPointer = nil; + _formElementPointer = nil; + } + return self; +} + +#pragma mark - Properties + +- (NSArray *)parseErrors +{ + return _errors; +} + +- (HTMLDocument *)document +{ + return _document ?: [self parseDocument]; +} + +#pragma mark - Parse + +- (void)initializeDocument +{ + if (_document == nil) { + _document = [HTMLDocument new]; + } + _document.readyState = HTMLDocumentLoading; + _document.quirksMode = HTMLQuirksModeNoQuirks; + _document.documentType = nil; + [_document removeAllChildNodes]; + + _fragmentParsingAlgorithm = NO; +} + +- (HTMLDocument *)parseDocument +{ + [self initializeDocument]; + [self runParser]; + return _document; +} + +- (NSArray *)parseFragmentWithContextElement:(HTMLElement *)contextElement +{ + if (contextElement == nil) { + return @[]; + } + + if ([_contextElement isEqual:contextElement]) { + HTMLElement *root = [_document firstElementMatchingSelector:rootSelector()]; + return root? root.childNodes.objectEnumerator.allObjects: @[]; + } + + [self initializeDocument]; + _tokenizer = [[HTMLTokenizer alloc] initWithString:_tokenizer.string]; + _tokenizer.parser = self; + + _contextElement = contextElement; + _fragmentParsingAlgorithm = YES; + + _document.quirksMode = _contextElement.ownerDocument ? _contextElement.ownerDocument.quirksMode : HTMLQuirksModeNoQuirks; + + if (_contextElement.htmlNamespace == HTMLNamespaceHTML) { + if ([_contextElement.tagName isEqualToAny:@"title", @"textarea", nil]) { + _tokenizer.state = HTMLTokenizerStateRCDATA; + } else if ([_contextElement.tagName isEqualToAny:@"style", @"xmp", @"iframe", @"noembed", @"noframes", nil]) { + _tokenizer.state = HTMLTokenizerStateRAWTEXT; + } else if ([_contextElement.tagName isEqualToString:@"script"]) { + _tokenizer.state = HTMLTokenizerStateScriptData; + } else if ([_contextElement.tagName isEqualToString:@"noscript"]) { + _tokenizer.state = HTMLTokenizerStateRAWTEXT; + } else if ([_contextElement.tagName isEqualToString:@"plaintext"]) { + _tokenizer.state = HTMLTokenizerStatePLAINTEXT; + } else { + _tokenizer.state = HTMLTokenizerStateData; + } + } + + HTMLElement *root = [[HTMLElement alloc] initWithTagName:@"html"]; + [_document appendNode:root]; + [_stackOfOpenElements pushElement:root]; + + if ([_contextElement.tagName isEqualToString:@"template"]) { + [_stackOfTemplateInsertionModes addObject:@(HTMLInsertionModeInTemplate)]; + } + + [self resetInsertionModeAppropriately]; + + _formElementPointer = _contextElement; + while (_formElementPointer != nil && ![_formElementPointer.tagName isEqualToString:@"form"]) { + _formElementPointer = _formElementPointer.parentElement; + } + + [self runParser]; + + return root.childNodes.objectEnumerator.allObjects; +} + +- (void)runParser +{ + for (HTMLToken *token in _tokenizer) { + if (_document.readyState == HTMLDocumentComplete) { + break; + } + [self processToken:token]; + } +} + +- (void)stopParsing +{ + [_stackOfOpenElements popAll]; + _document.readyState = HTMLDocumentComplete; +} + +#pragma mark - Processing + +- (void)processToken:(HTMLToken *)token +{ + BOOL (^ treeConstructionDispatcher)(HTMLElement *node) = ^BOOL(HTMLElement *node){ + + if (node == nil) { + return YES; + } + if (node.htmlNamespace == HTMLNamespaceHTML) { + return YES; + } + if (IsNodeMathMLTextIntegrationPoint(node)) { + if (token.type == HTMLTokenTypeStartTag) { + return ![token.asStartTagToken.tagName isEqualToAny:@"mglyph", @"malignmark", nil]; + } + if (token.type == HTMLTokenTypeCharacter) { + return YES; + } + } + if (node.htmlNamespace == HTMLNamespaceMathML && [node.tagName isEqualToString:@"annotation-xml"]) { + if (token.type == HTMLTokenTypeStartTag && [token.asTagToken.tagName isEqualToString:@"svg"]) { + return YES; + } + } + + if (IsNodeHTMLIntegrationPoint(node)) { + if (token.type == HTMLTokenTypeStartTag || token.type == HTMLTokenTypeCharacter) { + return YES; + } + } + if (token.type == HTMLTokenTypeEOF) { + return YES; + } + + return NO; + }; + + if (token.isParseError) { + [self emitParseError:@"Tokenizer Parser Error: %@", token.asParseError]; + return; + } + + if (_ignoreNextLineFeedCharacterToken) { + _ignoreNextLineFeedCharacterToken = NO; + if (token.isCharacterToken) { + NSString *characters = token.asCharacterToken.characters; + if ([characters characterAtIndex:0] == 0x000A) { + if (characters.length <= 1) { + return; + } + [token.asCharacterToken trimFormIndex:1]; + } + } + } + + if (treeConstructionDispatcher(self.adjustedCurrentNode)) { + [self processToken:token byApplyingRulesForInsertionMode:_insertionMode]; + } else { + [self processTokenByApplyingRulesForParsingTokensInForeignContent:token]; + } +} + +- (void)reprocessToken:(HTMLToken *)token +{ + [self processToken:token]; +} + +- (void)processToken:(HTMLToken *)token byApplyingRulesForInsertionMode:(HTMLInsertionMode)insertionMode +{ + switch (_insertionMode) { + case HTMLInsertionModeInitial: + return [self HTMLInsertionModeInitial:token]; + case HTMLInsertionModeBeforeHTML: + return [self HTMLInsertionModeBeforeHTML:token]; + case HTMLInsertionModeBeforeHead: + return [self HTMLInsertionModeBeforeHead:token]; + case HTMLInsertionModeInHead: + return [self HTMLInsertionModeInHead:token]; + case HTMLInsertionModeInHeadNoscript: + return [self HTMLInsertionModeInHeadNoscript:token]; + case HTMLInsertionModeAfterHead: + return [self HTMLInsertionModeAfterHead:token]; + case HTMLInsertionModeInBody: + return [self HTMLInsertionModeInBody:token]; + case HTMLInsertionModeText: + return [self HTMLInsertionModeText:token]; + case HTMLInsertionModeInTable: + return [self HTMLInsertionModeInTable:token]; + case HTMLInsertionModeInTableText: + return [self HTMLInsertionModeInTableText:token]; + case HTMLInsertionModeInCaption: + return [self HTMLInsertionModeInCaption:token]; + case HTMLInsertionModeInColumnGroup: + return [self HTMLInsertionModeInColumnGroup:token]; + case HTMLInsertionModeInTableBody: + return [self HTMLInsertionModeInTableBody:token]; + case HTMLInsertionModeInRow: + return [self HTMLInsertionModeInRow:token]; + case HTMLInsertionModeInCell: + return [self HTMLInsertionModeInCell:token]; + case HTMLInsertionModeInSelect: + return [self HTMLInsertionModeInSelect:token]; + case HTMLInsertionModeInSelectInTable: + return [self HTMLInsertionModeInSelectInTable:token]; + case HTMLInsertionModeInTemplate: + return [self HTMLInsertionModeInTemplate:token]; + case HTMLInsertionModeAfterBody: + return [self HTMLInsertionModeAfterBody:token]; + case HTMLInsertionModeInFrameset: + return [self HTMLInsertionModeInFrameset:token]; + case HTMLInsertionModeAfterFrameset: + return [self HTMLInsertionModeAfterFrameset:token]; + case HTMLInsertionModeAfterAfterBody: + return [self HTMLInsertionModeAfterAfterBody:token]; + case HTMLInsertionModeAfterAfterFrameset: + return [self HTMLInsertionModeAfterAfterFrameset:token]; + } +} + +#pragma mark - Nodes + +- (HTMLElement *)currentNode +{ + return _stackOfOpenElements.currentNode; +} + +- (HTMLElement *)adjustedCurrentNode +{ + if (_stackOfOpenElements.count == 1 && _fragmentParsingAlgorithm) { + return _contextElement; + } + return [self currentNode]; +} + +- (HTMLInsertionMode)currentTemplateInsertionMode +{ + if (_stackOfTemplateInsertionModes.count == 0) { + return _insertionMode; + } + return [_stackOfTemplateInsertionModes.firstObject unsignedIntegerValue]; +} + +#pragma mark - Emits + +- (void)emitParseError:(NSString *)format, ... NS_FORMAT_FUNCTION(1, 2) +{ + va_list args; + va_start(args, format); + NSString *message = [[NSString alloc] initWithFormat:format arguments:args]; + [_errors addObject:message]; + va_end(args); +} + +#pragma mark - Insertions & Manipulations + +- (HTMLNode *)appropriatePlaceForInsertingANodeWithOverrideTarget:(HTMLElement *)overrideTarget + beforeChildNode:(out HTMLElement * __autoreleasing *)child +{ + HTMLNode *target = self.currentNode; + if (overrideTarget != nil) { + target = overrideTarget; + } + + while (_fosterParenting && [[(HTMLElement *)target tagName] isEqualToAny:@"table", @"tbody", @"tfoot", @"thead", @"tr", nil]) { + HTMLElement *lastTemplate = nil; + HTMLElement *lastTable = nil; + + for (HTMLElement *element in _stackOfOpenElements.reverseObjectEnumerator) { + if ([element.tagName isEqualToString:@"template"]) { + lastTemplate = element; + break; + } + if ([element.tagName isEqualToString:@"table"]) { + lastTable = element; + break; + } + } + + if (lastTemplate != nil) { + HTMLTemplate *template = (HTMLTemplate *)lastTemplate; + target = template; + break; + } + + if (lastTable == nil) { + HTMLElement *htmlElement = _stackOfOpenElements.firstNode; + target = htmlElement; + break; + } + + if (lastTable.parentNode != nil) { + *child = lastTable; + target = lastTable.parentNode; + break; + } + + NSUInteger lastTableIndex = [_stackOfOpenElements indexOfElement:lastTable]; + HTMLElement *previousNode = _stackOfOpenElements[lastTableIndex]; + target = previousNode; + break; + } + + if ([target isKindOfClass:[HTMLTemplate class]]) { + target = [(HTMLTemplate *)target content]; + } + return target; +} + +- (void)insertComment:(HTMLCommentToken *)token +{ + [self insertComment:token asChildOfNode:nil]; +} + +- (void)insertComment:(HTMLCommentToken *)token asChildOfNode:(HTMLNode *)node +{ + HTMLNode *parent = node; + HTMLElement *child = nil; + if (parent == nil) { + parent = [self appropriatePlaceForInsertingANodeWithOverrideTarget:nil beforeChildNode:&child]; + } + + HTMLComment *comment = [[HTMLComment alloc] initWithData:token.data]; + [parent insertNode:comment beforeChildNode:child]; +} + +- (HTMLElement *)createElementForToken:(HTMLTagToken *)token inNamespace:(HTMLNamespace)htmlNamespace +{ + HTMLElement *element = [[HTMLElement alloc] initWithTagName:token.tagName + namespace:htmlNamespace + attributes:token.attributes]; + return element; +} + +- (HTMLElement *)insertElementForToken:(HTMLTagToken *)token +{ + return [self insertForeignElementForToken:token inNamespace:HTMLNamespaceHTML]; +} + +- (HTMLElement *)insertForeignElementForToken:(HTMLTagToken *)token inNamespace:(HTMLNamespace)namespace +{ + HTMLElement *element = [self createElementForToken:token inNamespace:namespace]; + return [self insertElement:element]; +} + +- (HTMLElement *)insertElement:(HTMLElement *)element +{ + HTMLElement *child = nil; + HTMLNode *adjustedInsertionLocation = [self appropriatePlaceForInsertingANodeWithOverrideTarget:nil + beforeChildNode:&child]; + [adjustedInsertionLocation insertNode:element beforeChildNode:child]; + [_stackOfOpenElements pushElement:element]; + return element; +} + +- (void)insertCharacters:(NSString *)data +{ + HTMLElement *child = nil; + HTMLNode *adjustedInsertionLocation = [self appropriatePlaceForInsertingANodeWithOverrideTarget:nil + beforeChildNode:&child]; + if (adjustedInsertionLocation.nodeType != HTMLNodeDocument) { + if (child != nil && child.previousSibling.nodeType == HTMLNodeText) { + HTMLText *textNode = (HTMLText *)child.previousSibling; + [textNode appendData:data]; + } else if (adjustedInsertionLocation.lastChild.nodeType == HTMLNodeText) { + HTMLText *textNode = (HTMLText *)adjustedInsertionLocation.lastChild; + [textNode appendData:data]; + } else { + HTMLText *text = [[HTMLText alloc] initWithData:data]; + [adjustedInsertionLocation insertNode:text beforeChildNode:child]; + } + } +} + +- (void)applyGenericParsingAlgorithmForToken:(HTMLStartTagToken *)token withTokenizerState:(HTMLTokenizerState)state +{ + [self insertElementForToken:token]; + _tokenizer.state = state; + _originalInsertionMode = _insertionMode; + [self switchInsertionMode:HTMLInsertionModeText]; +} + +- (void)reconstructActiveFormattingElements +{ + if (_listOfActiveFormattingElements.isEmpty) { + return; + } + + id last = _listOfActiveFormattingElements.lastEntry; + if (last == [HTMLMarker marker] || [_stackOfOpenElements containsElement:last]) { + return; + } + + NSInteger index = _listOfActiveFormattingElements.count - 1; + HTMLElement *entry = _listOfActiveFormattingElements[index]; + + // Reconstruct the active formatting elements + // https://html.spec.whatwg.org/multipage/syntax.html#reconstruct-the-active-formatting-elements + + // Rewind phase + while (![entry isEqual:[HTMLMarker marker]] && ![_stackOfOpenElements containsElement:entry]) { + if (index == 0) { + index--; + break; + } + entry = _listOfActiveFormattingElements[--index]; + } + + while (YES) { + // Advance phase + entry = _listOfActiveFormattingElements[++index]; + + // Create phase + HTMLStartTagToken *token = [[HTMLStartTagToken alloc] initWithTagName:entry.tagName + attributes:entry.attributes]; + HTMLElement *element = [self insertElementForToken:token]; + [_listOfActiveFormattingElements replaceElementAtIndex:index withElement:element]; + + if (element == _listOfActiveFormattingElements.lastEntry) { + break; + } + } +} + +- (void)generateImpliedEndTagsExceptForElement:(NSString *)tagName +{ + while ([self.currentNode.tagName isEqualToAny:@"dd", @"dt", @"li", @"option", @"optgroup", @"p", @"rb", @"rp", @"rt", @"rtc", nil] && + ![self.currentNode.tagName isEqualToString:tagName]) { + [_stackOfOpenElements popCurrentNode]; + } +} + +- (void)generateAllImpliedEndTagsThoroughly +{ + while ([self.currentNode.tagName isEqualToAny:@"caption", @"colgroup", @"dd", @"dt", @"li", @"option", @"optgroup", @"p", + @"rb", @"rp", @"rt", @"rtc", @"tbody", @"td", @"tfoot", @"th", @"thead", @"tr", nil]) { + [_stackOfOpenElements popCurrentNode]; + } +} + +- (void)closePElement +{ + [self generateImpliedEndTagsExceptForElement:@"p"]; + if (![self.currentNode.tagName isEqualToString:@"p"]) { + [self emitParseError:@"Current node being closed is not a

    element"]; + } + [_stackOfOpenElements popElementsUntilElementPoppedWithTagName:@"p"]; +} + +- (BOOL)runAdoptionAgencyAlgorithmForTagName:(NSString *)tagName +{ + if ([self.currentNode.tagName isEqualToString:tagName] && + ![_listOfActiveFormattingElements containsElement:self.currentNode]) { + [_stackOfOpenElements popCurrentNode]; + return NO; + } + + for (int outerLoopCounter = 0; outerLoopCounter < 8; outerLoopCounter++) { + + HTMLElement *formattingElement = [_listOfActiveFormattingElements formattingElementWithTagName:tagName]; + if (formattingElement == nil) { + return YES; + } + + if (![_stackOfOpenElements containsElement:formattingElement]) { + [self emitParseError:@"Formatting element <%@> is not in the Stack of Open Elements (Adoption Agency)", tagName]; + [_listOfActiveFormattingElements removeElement:formattingElement]; + return NO; + } + + if (![_stackOfOpenElements hasElementInScopeWithTagName:formattingElement.tagName]) { + [self emitParseError:@"Formatting element <%@> is not in scope (Adoption Agency)", tagName]; + return NO; + } + + if (![formattingElement isEqual:self.currentNode]) { + [self emitParseError:@"Formatting element <%@> is not the current node (Adoption Agency)", tagName]; + } + + NSUInteger formattingElementIndex = [_stackOfOpenElements indexOfElement:formattingElement]; + HTMLElement *furthestBlock = [_stackOfOpenElements furthestBlockAfterIndex:formattingElementIndex]; + + if (furthestBlock == nil) { + [_stackOfOpenElements popElementsUntilElementPopped:formattingElement]; + [_listOfActiveFormattingElements removeElement:formattingElement]; + return NO; + } + + HTMLElement *commonAncestor = _stackOfOpenElements[formattingElementIndex - 1]; + NSUInteger bookmark = [_listOfActiveFormattingElements indexOfElement:formattingElement]; + + HTMLElement *node = furthestBlock; + HTMLElement *lastNode = furthestBlock; + + NSUInteger index = [_stackOfOpenElements indexOfElement:node]; + + int innerLoopCounter = 0; + while (YES) { + + innerLoopCounter += 1; + index -= 1; + + node = _stackOfOpenElements[index]; + + if ([node isEqual:formattingElement]) { + break; + } + + if (innerLoopCounter > 3 && [_listOfActiveFormattingElements containsElement:node]) { + [_listOfActiveFormattingElements removeElement:node]; + continue; + } + + if (![_listOfActiveFormattingElements containsElement:node]) { + [_stackOfOpenElements removeElement:node]; + continue; + } + + HTMLElement *newElement = [node copy]; + [_listOfActiveFormattingElements replaceElementAtIndex:[_listOfActiveFormattingElements indexOfElement:node] + withElement:newElement]; + [_stackOfOpenElements replaceElementAtIndex:[_stackOfOpenElements indexOfElement:node] + withElement:newElement]; + node = newElement; + + if ([lastNode isEqual:furthestBlock]) { + bookmark = [_listOfActiveFormattingElements indexOfElement:node] + 1; + } + + [lastNode.parentNode removeChildNode:lastNode]; + [node appendNode:lastNode]; + lastNode = node; + } + + HTMLElement *child = nil; + HTMLNode *parent = [self appropriatePlaceForInsertingANodeWithOverrideTarget:commonAncestor + beforeChildNode:&child]; + [parent insertNode:lastNode beforeChildNode:child]; + + HTMLElement *newElement = [formattingElement copy]; + [furthestBlock reparentChildNodesIntoNode:newElement]; + [furthestBlock appendNode:newElement]; + + [_listOfActiveFormattingElements removeElement:formattingElement]; + [_listOfActiveFormattingElements insertElement:newElement atIndex:bookmark]; + + [_stackOfOpenElements removeElement:formattingElement]; + NSUInteger furthestBlockIndex = [_stackOfOpenElements indexOfElement:furthestBlock]; + [_stackOfOpenElements insertElement:newElement atIndex:furthestBlockIndex + 1]; + } + return NO; +} + +- (void)closeTheCell +{ + [self generateImpliedEndTagsExceptForElement:nil]; + if (![self.currentNode.tagName isEqualToAny:@"td", @"th", nil]) { + [self emitParseError:@"Closing misnested Cell <%@>", self.currentNode.tagName]; + } + [_stackOfOpenElements popElementsUntilAnElementPoppedWithAnyOfTagNames:@[@"td", @"th"]]; + [_listOfActiveFormattingElements clearUptoLastMarker]; + [self switchInsertionMode:HTMLInsertionModeInRow]; +} + +#pragma mark - State Machine + +- (void)switchInsertionMode:(HTMLInsertionMode)mode +{ + if (mode == HTMLInsertionModeText || mode == HTMLInsertionModeInTableText) { + _originalInsertionMode = _insertionMode; + } + _insertionMode = mode; +} + +- (void)resetInsertionModeAppropriately +{ + BOOL last = NO; + HTMLElement *node = _stackOfOpenElements.lastNode; + NSUInteger nodeIndex = _stackOfOpenElements.count - 1; + + while (YES) { + + if (node == _stackOfOpenElements.firstNode) { + last = YES; + if (_fragmentParsingAlgorithm) { + node = _contextElement; + } + } + + if ([node.tagName isEqualToString:@"select"]) { + if (last == NO) { + HTMLElement *ancestor = node; + NSUInteger ancestorIndex = nodeIndex; + + while (YES) { + if (ancestor == _stackOfOpenElements.firstNode) { + break; + } + + ancestorIndex--; + ancestor = _stackOfOpenElements[ancestorIndex]; + + if ([ancestor.tagName isEqualToString:@"template"]) { + break; + } + + if ([ancestor.tagName isEqualToString:@"table"]) { + [self switchInsertionMode:HTMLInsertionModeInTable]; + return; + } + } + } + [self switchInsertionMode:HTMLInsertionModeInSelect]; + return; + } + + if (last == NO) { + if ([node.tagName isEqualToAny:@"td", @"th", nil]) { + [self switchInsertionMode:HTMLInsertionModeInCell]; + return; + } + } + + if ([node.tagName isEqualToString:@"tr"]) { + [self switchInsertionMode:HTMLInsertionModeInRow]; + return; + } + + if ([node.tagName isEqualToAny:@"tbody", @"thead", @"tfoot", nil]) { + [self switchInsertionMode:HTMLInsertionModeInTableBody]; + return; + } + + if ([node.tagName isEqualToString:@"caption"]) { + [self switchInsertionMode:HTMLInsertionModeInCaption]; + return; + } + + if ([node.tagName isEqualToString:@"colgroup"]) { + [self switchInsertionMode:HTMLInsertionModeInColumnGroup]; + return; + } + + if ([node.tagName isEqualToString:@"table"]) { + [self switchInsertionMode:HTMLInsertionModeInTable]; + return; + } + + if ([node.tagName isEqualToString:@"template"]) { + [self switchInsertionMode:self.currentTemplateInsertionMode]; + return; + } + + if (last == NO) { + if ([node.tagName isEqualToString:@"head"]) { + [self switchInsertionMode:HTMLInsertionModeInHead]; + return; + } + } + + if ([node.tagName isEqualToString:@"body"]) { + [self switchInsertionMode:HTMLInsertionModeInBody]; + return; + } + + if ([node.tagName isEqualToString:@"frameset"]) { + [self switchInsertionMode:HTMLInsertionModeInFrameset]; + return; + } + + if ([node.tagName isEqualToString:@"html"]) { + if (_headElementPointer == nil) { + [self switchInsertionMode:HTMLInsertionModeBeforeHead]; + } else { + [self switchInsertionMode:HTMLInsertionModeAfterHead]; + } + return; + } + + if (last) { + [self switchInsertionMode:HTMLInsertionModeInBody]; + return; + } + + nodeIndex--; + node = _stackOfOpenElements[nodeIndex]; + } +} + +#pragma mark - Insertion Modes + +- (void)HTMLInsertionModeInitial:(HTMLToken *)token +{ + switch (token.type) { + case HTMLTokenTypeCharacter: + { + [token.asCharacterToken trimLeadingWhitespace]; + + if (token.asCharacterToken.isEmpty) { + return; + } + break; + } + case HTMLTokenTypeComment: + [self insertComment:token.asCommentToken asChildOfNode:_document]; + return; + case HTMLTokenTypeDoctype: + { + HTMLDOCTYPEToken *doctypeToken = token.asDoctypeToken; + + HTMLDocumentType *doctype = [[HTMLDocumentType alloc] initWithName:doctypeToken.name + publicIdentifier:doctypeToken.publicIdentifier + systemIdentifier:doctypeToken.systemIdentifier]; + + if (!doctype.isValid) { + [self emitParseError:@"Invalid DOCTYPE"]; + } + + _document.documentType = doctype; + _document.quirksMode = doctype.quirksMode; + + if (doctypeToken.forceQuirks) { + _document.quirksMode = HTMLQuirksModeQuirks; + } + [self switchInsertionMode:HTMLInsertionModeBeforeHTML]; + return; + } + default: + break; + } + + [self emitParseError:@"Expected a DOCTYPE"]; + _document.quirksMode = HTMLQuirksModeQuirks; + [self switchInsertionMode:HTMLInsertionModeBeforeHTML]; + [self reprocessToken:token]; +} + +- (void)HTMLInsertionModeBeforeHTML:(HTMLToken *)token +{ + switch (token.type) { + case HTMLTokenTypeDoctype: + [self emitParseError:@"Unexpected DOCTYPE Token before "]; + return; + case HTMLTokenTypeComment: + [self insertComment:token.asCommentToken asChildOfNode:_document]; + return; + case HTMLTokenTypeCharacter: + { + [token.asCharacterToken trimLeadingWhitespace]; + + if (token.asCharacterToken.isEmpty) { + return; + } + break; + } + case HTMLTokenTypeStartTag: + if ([token.asStartTagToken.tagName isEqualToString:@"html"]) { + HTMLElement *html = [self createElementForToken:token.asTagToken inNamespace:HTMLNamespaceHTML]; + [_document appendNode:html]; + [_stackOfOpenElements pushElement:html]; + [self switchInsertionMode:HTMLInsertionModeBeforeHead]; + return; + } + break; + case HTMLTokenTypeEndTag: + if (![token.asEndTagToken.tagName isEqualToAny:@"head", @"body", @"html", @"br", nil]) { + [self emitParseError:@"Unexpected end tag before ", token.asEndTagToken.tagName]; + return; + } + break; + default: + break; + } + + HTMLElement *html = [[HTMLElement alloc] initWithTagName:@"html"]; + [_document appendNode:html]; + [_stackOfOpenElements pushElement:html]; + [self switchInsertionMode:HTMLInsertionModeBeforeHead]; + [self reprocessToken:token]; +} + +- (void)HTMLInsertionModeBeforeHead:(HTMLToken *)token +{ + switch (token.type) { + case HTMLTokenTypeCharacter: + { + [token.asCharacterToken trimLeadingWhitespace]; + + if (token.asCharacterToken.isEmpty) { + return; + } + break; + } + case HTMLTokenTypeComment: + [self insertComment:token.asCommentToken]; + return; + case HTMLTokenTypeDoctype: + [self emitParseError:@"Unexpected DOCTYPE Token before "]; + return; + case HTMLTokenTypeStartTag: + if ([token.asStartTagToken.tagName isEqualToString:@"html"]) { + [self HTMLInsertionModeInBody:token]; + } else if ([token.asStartTagToken.tagName isEqualToString:@"head"]) { + HTMLElement *head = [self insertElementForToken:token.asTagToken]; + _headElementPointer = head; + [self switchInsertionMode:HTMLInsertionModeInHead]; + } else { + break; + } + return; + case HTMLTokenTypeEndTag: + if (![token.asEndTagToken.tagName isEqualToAny:@"head", @"body", @"html", @"br", nil]) { + [self emitParseError:@"Unexpected end tag before ", token.asEndTagToken.tagName]; + return; + } + break; + default: + break; + } + + HTMLStartTagToken *headToken = [[HTMLStartTagToken alloc] initWithTagName:@"head"]; + HTMLElement *head = [self insertElementForToken:headToken]; + _headElementPointer = head; + [self switchInsertionMode:HTMLInsertionModeInHead]; + [self reprocessToken:token]; +} + +- (void)HTMLInsertionModeInHead:(HTMLToken *)token +{ + switch (token.type) { + case HTMLTokenTypeCharacter: + { + HTMLCharacterToken *leadingWhiteSpace = [token.asCharacterToken tokenBySplitingLeadingWhiteSpace]; + if (leadingWhiteSpace) { + [self insertCharacters:leadingWhiteSpace.characters]; + } + + if (token.asCharacterToken.isEmpty) { + return; + } + break; + } + case HTMLTokenTypeComment: + [self insertComment:token.asCommentToken]; + return; + case HTMLTokenTypeDoctype: + [self emitParseError:@"Unexpected DOCTYPE Token in "]; + return; + case HTMLTokenTypeStartTag: + if ([token.asStartTagToken.tagName isEqualToString:@"html"]) { + [self HTMLInsertionModeInBody:token]; + } else if ([token.asStartTagToken.tagName isEqualToAny:@"base", @"basefont", @"bgsound", @"link", nil]) { + [self insertElementForToken:token.asStartTagToken]; + [_stackOfOpenElements popCurrentNode]; + } else if ([token.asStartTagToken.tagName isEqualToString:@"meta"]) { + [self insertElementForToken:token.asStartTagToken]; + [_stackOfOpenElements popCurrentNode]; + } else if ([token.asStartTagToken.tagName isEqualToString:@"title"]) { + [self applyGenericParsingAlgorithmForToken:token.asStartTagToken withTokenizerState:HTMLTokenizerStateRCDATA]; + } else if ([token.asStartTagToken.tagName isEqualToAny:@"noscript", @"noframes", @"style", nil]) { + [self applyGenericParsingAlgorithmForToken:token.asStartTagToken withTokenizerState:HTMLTokenizerStateRAWTEXT]; + } else if ([token.asStartTagToken.tagName isEqualToString:@"script"]) { + HTMLElement *child = nil; + HTMLNode *adjustedInsertionLocation = [self appropriatePlaceForInsertingANodeWithOverrideTarget:nil + beforeChildNode:&child]; + HTMLElement *script = [self createElementForToken:token.asStartTagToken inNamespace:HTMLNamespaceHTML]; + [adjustedInsertionLocation insertNode:script beforeChildNode:child]; + [_stackOfOpenElements pushElement:script]; + _tokenizer.state = HTMLTokenizerStateScriptData; + _originalInsertionMode = _insertionMode; + [self switchInsertionMode:HTMLInsertionModeText]; + } else if ([token.asStartTagToken.tagName isEqualToString:@"head"]) { + [self emitParseError:@"Unexpected start tag in "]; + } else if ([token.asStartTagToken.tagName isEqualToString:@"template"]) { + HTMLTemplate *template = [HTMLTemplate new]; + [self insertElement:template]; + [_listOfActiveFormattingElements addMarker]; + _framesetOkFlag = NO; + [self switchInsertionMode:HTMLInsertionModeInTemplate]; + [_stackOfTemplateInsertionModes addObject:@(HTMLInsertionModeInTemplate)]; + } else { + break; + } + return; + case HTMLTokenTypeEndTag: + if ([token.asEndTagToken.tagName isEqualToString:@"head"]) { + [_stackOfOpenElements popCurrentNode]; + [self switchInsertionMode:HTMLInsertionModeAfterHead]; + } else if ([token.asEndTagToken.tagName isEqualToAny:@"body", @"html", @"br", nil]) { + break; + } else if ([token.asEndTagToken.tagName isEqualToString:@"template"]) { + if (![_stackOfOpenElements containsElementWithTagName:@"template"]) { + [self emitParseError:@"Unexpected end tag in "]; + return; + } + [self generateAllImpliedEndTagsThoroughly]; + if (![self.currentNode.tagName isEqualToString:@"template"]) { + [self emitParseError:@"Unexpected end tag in ", self.currentNode.tagName]; + } + [_stackOfOpenElements popElementsUntilTemplateElementPopped]; + [_listOfActiveFormattingElements clearUptoLastMarker]; + [_stackOfTemplateInsertionModes removeLastObject]; + [self resetInsertionModeAppropriately]; + } else { + [self emitParseError:@"Unexpected end tag in ", token.asEndTagToken.tagName]; + return; + } + return; + default: + break; + } + + [_stackOfOpenElements popCurrentNode]; + [self switchInsertionMode:HTMLInsertionModeAfterHead]; + [self reprocessToken:token]; +} + +- (void)HTMLInsertionModeInHeadNoscript:(HTMLToken *)token +{ + switch (token.type) { + case HTMLTokenTypeDoctype: + [self emitParseError:@"Unexpected DOCTYPE Token in

    in "]; + } else { + if ([_stackOfOpenElements hasElementInButtonScopeWithTagName:@"p"]) { + [self closePElement]; + } + HTMLElement *form = [self insertElementForToken:token]; + if (![_stackOfOpenElements containsElementWithTagName:@"template"]) { + _formElementPointer = form; + } + } + } else if ([tagName isEqualToAny:@"li", @"dd", @"dt", nil]) { + /** li, dd & dt cases are all same, hence the merge */ + _framesetOkFlag = NO; + + // Start Tag: li, dd, dt + // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inbody + + NSDictionary *map = @{@"li": @[@"li"], + @"dd": @[@"dd", @"dt"], + @"dt": @[@"dd", @"dt"]}; + + for (HTMLElement *node in _stackOfOpenElements.reverseObjectEnumerator) { + if ([map[tagName] containsObject:node.tagName]) { + [self generateImpliedEndTagsExceptForElement:node.tagName]; + if (![self.currentNode.tagName isEqualToString:node.tagName]) { + [self emitParseError:@"Unexpected Start Tag <%@> in ", node.tagName]; + } + [_stackOfOpenElements popElementsUntilElementPoppedWithTagName:node.tagName]; + break; + } else if (IsSpecialElement(node) && ![node.tagName isEqualToAny:@"address", @"div", @"p", nil]) { + break; + } + } + + if ([_stackOfOpenElements hasElementInButtonScopeWithTagName:@"p"]) { + [self closePElement]; + } + [self insertElementForToken:token]; + } else if ([tagName isEqualToString:@"plaintext"]) { + if ([_stackOfOpenElements hasElementInButtonScopeWithTagName:@"p"]) { + [self closePElement]; + } + [self insertElementForToken:token]; + _tokenizer.state = HTMLTokenizerStatePLAINTEXT; + } else if ([tagName isEqualToString:@"button"]) { + if ([_stackOfOpenElements hasElementInScopeWithTagName:@"button"]) { + [self emitParseError:@"Unexpected nested Start Tag

    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 literal 365896 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%0DlVb+TNRif6(DS9rzB1 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 diff --git a/ReinventlyMoodboards.sketchplugin/Contents/Sketch/manifest.json b/ReinventlyMoodboards.sketchplugin/Contents/Sketch/manifest.json index 4ba4665..f96945e 100644 --- a/ReinventlyMoodboards.sketchplugin/Contents/Sketch/manifest.json +++ b/ReinventlyMoodboards.sketchplugin/Contents/Sketch/manifest.json @@ -1,10 +1,10 @@ { "author": "Reinvently", "identifier": "com.reinvently.sketch.moodboadrs", - "version": "1.0.0", + "version": "1.1.0", "description": "A streamlined Sketch plugin for creating moodboards quickly and easily. Just do a search, check the suitable images, and - voila - you have a beautiful moodboard. Keep inspired!", "authorEmail": "hello@reinvently.com", - "name": "Reinvently MoodBooards", + "name": "Moodboard Builder", "appcast": "https://raw.githubusercontent.com/Reinvently/moodboards-sketch-plugin/master/appcast.xml", "commands": [ { @@ -25,7 +25,7 @@ "shortcut": "" }, { - "name": "Feedback", + "name": "Feedback (hello@reinvently.com)", "identifier": "com.reinvently.sketch.feedback", "handler": "openFeedback", "script": "script.cocoascript", @@ -33,7 +33,7 @@ } ], "menu": { - "title": "Reinvently MoodBooards", + "title": "Moodboard Builder", "items": [ "com.reinvently.sketch.run", "-", diff --git a/ReinventlyMoodboards.sketchplugin/Contents/Sketch/script.cocoascript b/ReinventlyMoodboards.sketchplugin/Contents/Sketch/script.cocoascript index 8b86629..ac66054 100644 --- a/ReinventlyMoodboards.sketchplugin/Contents/Sketch/script.cocoascript +++ b/ReinventlyMoodboards.sketchplugin/Contents/Sketch/script.cocoascript @@ -1,17 +1,28 @@ @import 'SketchPlugin.framework/RSPHelper.js' var onRun = function(context) { - var main = RSPMain.alloc().init(); - main.run(context) + var main = RSPMain.alloc().init(); + main.run(context) }; function openHelp(){ - openURL('https://github.com/Reinvently/moodboards-sketch-plugin'); + openURL('http://reinvently.com/moodboard-builder-sketch-plugin/'); } -function openFeedback(){ - openURL('https://github.com/Reinvently/moodboards-sketch-plugin/issues/new'); +function openFeedback(context){ + //reference the Sketch Document + var doc = context.document; + + var body = ""; + var emailService = NSSharingService.sharingServiceNamed(NSSharingServiceNameComposeEmail); + emailService.recipients = ["hello@reinvently.com"]; + emailService.subject = "Feedback Moodboard Builder"; + + emailService.performWithItems([body]); + + doc.showMessage("Thanks!"); } function openURL(url){ - NSWorkspace.sharedWorkspace().openURL(NSURL.URLWithString(url)); -} \ No newline at end of file + NSWorkspace.sharedWorkspace().openURL(NSURL.URLWithString(url)); +} + diff --git a/appcast.xml b/appcast.xml index 34cbf8e..3ded7cc 100755 --- a/appcast.xml +++ b/appcast.xml @@ -16,5 +16,17 @@ + + Version 1.1.0 + + +