+2008-03-06 Darin Adler <darin@apple.com>
+
+ Reviewed by Mitz.
+
+ - fix http://bugs.webkit.org/show_bug.cgi?id=17526
+ REGRESSION: iframes are added to Safari's History menu
+ by separating the visited link machinery from global history
+
+ This should also make page loading faster due to more efficient visited link coloring.
+
+ * WebCore.base.exp: Updated.
+ * WebCore.vcproj/WebCore.vcproj: Added PageGroup.h/cpp, removed GlobalHistory.h/cpp.
+ * WebCore.xcodeproj/project.pbxproj: Ditto. Also removed WebCoreHistory.h/m.
+
+ * css/CSSStyleSelector.cpp: Updated includes.
+ (WebCore::CSSStyleSelector::initElementAndPseudoState): Eliminated code to set
+ currentEncodedURL.
+ (WebCore::checkPseudoState): Moved most of the code inside a new
+ PageGroup::isLinkVisited function.
+ (WebCore::CSSStyleSelector::canShareStyleWithElement): Tightened code a bit by using
+ references and only getting colors when needed.
+ (WebCore::CSSStyleSelector::getColorFromPrimitiveValue): Ditto.
+ * css/CSSStyleSelector.h: Removed EncodedURL, m_encodedURL, and setEncodedURL.
+
+ * dom/Document.cpp:
+ (WebCore::Document::attach): Removed call to setEncodedURL.
+ (WebCore::Document::setURL): Ditto.
+ (WebCore::Document::recalcStyleSelector): Ditto.
+
+ * loader/FrameLoader.cpp:
+ (WebCore::FrameLoader::addBackForwardItemClippedAtTarget): Changed code to use
+ early exit idiom to be a little more readable.
+ (WebCore::FrameLoader::urlsMatchItem): Change to use a reference for slightly
+ better efficiency.
+ (WebCore::FrameLoader::goToItem): Use early exit idiom to be a little more
+ readable.
+ (WebCore::FrameLoader::updateHistoryForStandardLoad): Moved history code back
+ in here and got rid of the helper function updateGlobalHistory, restoring the
+ logic before r30549. Also added a call to the new addVisitedLink function.
+ (WebCore::FrameLoader::updateHistoryForClientRedirect): Added code to call
+ addVisitedLink here.
+ (WebCore::FrameLoader::updateHistoryForBackForwardNavigation): Removed comment.
+ (WebCore::FrameLoader::updateHistoryForReload): Removed call to
+ updateGlobalHistory; we can just go without updating global history or
+ visited links here, at least for now, since it's not clear that a reload
+ is a "history event".
+ (WebCore::FrameLoader::updateHistoryForRedirectWithLockedHistory): Moved
+ history code back where it was, and added the call to addVisitedLink, just
+ as in updateHistoryForStandardLoad above.
+ * loader/FrameLoader.h: Removed updateGlobalHistory function.
+
+ * page/Chrome.cpp:
+ (WebCore::ChromeClient::populateVisitedLinks): Added. Empty placeholder so we
+ don't have to implement this for every port all at once.
+ (WebCore::PageGroupLoadDeferrer::PageGroupLoadDeferrer): Changed to use the
+ new PageGroup class.
+ * page/ChromeClient.h: Added populateVisitedLinks function, used to fill the
+ visited links set from the global history at application startup time.
+
+ * page/FrameTree.cpp:
+ (WebCore::FrameTree::find): Updated to use the new PageGroup class.
+
+ * page/GlobalHistory.h: Removed.
+ * page/win/GlobalHistoryWin.cpp: Removed.
+ * page/mac/GlobalHistoryMac.mm: Removed.
+ * platform/mac/WebCoreHistory.h: Removed.
+ * platform/mac/WebCoreHistory.m: Removed.
+ * platform/win/WebCoreHistory.cpp: Removed.
+ * platform/win/WebCoreHistory.h: Removed.
+
+ * page/Page.cpp:
+ (WebCore::Page::Page): Set m_group to 0.
+ (WebCore::Page::setGroupName): Set up m_group. If the page is not in any
+ group, set it to 0 for now to postpone the cost of creating a group.
+ (WebCore::Page::initGroup): Added. Sets m_group to point to a single-page
+ group; used when getting a group.
+ (WebCore::Page::removeAllVisitedLinks): Added. Calls removeVisitedLinks
+ on all page groups.
+ * page/Page.h: Moved enums inside the WebCore namespace. Removed the
+ frameNamespace function and instead added the group and groupPtr functions.
+
+ * page/PageGroup.cpp: Added. Contains all the visited code from the
+ CSSStyleSelector in the isVisitedLink function, but more efficient because
+ we don't allocate memory for the buffer.
+ * page/PageGroup.h: Added.
+
+ * platform/gtk/TemporaryLinkStubs.cpp: Removed historyContains.
+ * platform/qt/TemporaryLinkStubs.cpp: Removed unneeded include.
+ * platform/wx/TemporaryLinkStubs.cpp: Removed historyContains.
+
2008-03-06 Mark Rowe <mrowe@apple.com>
Fix 64-bit Mac build.
__ZN7WebCore4Page6goBackEv
__ZN7WebCore4Page8goToItemEPNS_11HistoryItemENS_13FrameLoadTypeE
__ZN7WebCore4Page9goForwardEv
+__ZN7WebCore4Page9initGroupEv
__ZN7WebCore4PageC1EPNS_12ChromeClientEPNS_17ContextMenuClientEPNS_12EditorClientEPNS_10DragClientEPNS_15InspectorClientE
__ZN7WebCore4PageD1Ev
__ZN7WebCore5Cache11setDisabledEb
__ZN7WebCore9HTMLNames8hrefAttrE
__ZN7WebCore9PageCache11setCapacityEi
__ZN7WebCore9PageCache27releaseAutoreleasedPagesNowEv
+__ZN7WebCore9PageGroup14addVisitedLinkEPKtm
+__ZN7WebCore9PageGroup21removeAllVisitedLinksEv
__ZN7WebCore9Selection22expandUsingGranularityENS_15TextGranularityE
__ZN7WebCore9TimerBase4stopEv
__ZN7WebCore9TimerBase5startEdd
>\r
</File>\r
<File\r
- RelativePath="..\bridge\GlobalHistory.h"\r
- >\r
- </File>\r
- <File\r
RelativePath="..\page\History.cpp"\r
>\r
</File>\r
>\r
</File>\r
<File\r
+ RelativePath="..\page\PageGroup.cpp"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath="..\page\PageGroup.h"\r
+ >\r
+ </File>\r
+ <File\r
RelativePath="..\page\Plugin.h"\r
>\r
</File>\r
>\r
</File>\r
<File\r
- RelativePath="..\page\win\GlobalHistoryWin.cpp"\r
- >\r
- </File>\r
- <File\r
RelativePath="..\page\win\PageWin.cpp"\r
>\r
</File>\r
>\r
</File>\r
<File\r
- RelativePath="..\platform\win\WebCoreHistory.cpp"\r
- >\r
- </File>\r
- <File\r
- RelativePath="..\platform\win\WebCoreHistory.h"\r
- >\r
- </File>\r
- <File\r
RelativePath="..\platform\win\WebCoreTextRenderer.cpp"\r
>\r
</File>\r
1AE82FED0CAB07EE002237AE /* JSSQLResultSet.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AE82FEB0CAB07EE002237AE /* JSSQLResultSet.h */; };
1AE830440CAB0ED1002237AE /* JSDatabaseCustom.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1AE830420CAB0ED1002237AE /* JSDatabaseCustom.cpp */; };
1AF326460D78B5530068F0C4 /* AXObjectCacheMac.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1AF326400D78B5530068F0C4 /* AXObjectCacheMac.mm */; };
- 1AF326470D78B5530068F0C4 /* GlobalHistoryMac.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1AF326410D78B5530068F0C4 /* GlobalHistoryMac.mm */; };
1AF326480D78B5530068F0C4 /* WebCoreAXObject.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AF326420D78B5530068F0C4 /* WebCoreAXObject.h */; };
1AF326490D78B5530068F0C4 /* WebCoreAXObject.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1AF326430D78B5530068F0C4 /* WebCoreAXObject.mm */; };
1AF326780D78B9440068F0C4 /* AXObjectCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AF326760D78B9440068F0C4 /* AXObjectCache.h */; };
1AF326790D78B9440068F0C4 /* EditorClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AF326770D78B9440068F0C4 /* EditorClient.h */; settings = {ATTRIBUTES = (Private, ); }; };
- 1AF3267B0D78B94E0068F0C4 /* GlobalHistory.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AF3267A0D78B94E0068F0C4 /* GlobalHistory.h */; };
1AFE117D0CBFFB36003017FA /* SQLResultSetRowList.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1AFE117B0CBFFB36003017FA /* SQLResultSetRowList.cpp */; };
1AFE117E0CBFFB36003017FA /* SQLResultSetRowList.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AFE117C0CBFFB36003017FA /* SQLResultSetRowList.h */; };
1AFE11990CBFFCC4003017FA /* JSSQLResultSetRowList.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1AFE11970CBFFCC4003017FA /* JSSQLResultSetRowList.cpp */; };
85FF315A0AAFBFCB00374F38 /* DOMKeyboardEvent.h in Headers */ = {isa = PBXBuildFile; fileRef = 85FF31580AAFBFCB00374F38 /* DOMKeyboardEvent.h */; };
85FF315B0AAFBFCB00374F38 /* DOMKeyboardEvent.mm in Sources */ = {isa = PBXBuildFile; fileRef = 85FF31590AAFBFCB00374F38 /* DOMKeyboardEvent.mm */; };
929264770B61FC7200B41D34 /* JSDocumentCustom.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 929264760B61FC7200B41D34 /* JSDocumentCustom.cpp */; };
+ 9302B0BD0D79F82900C7EE83 /* PageGroup.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9302B0BC0D79F82900C7EE83 /* PageGroup.cpp */; };
+ 9302B0BF0D79F82C00C7EE83 /* PageGroup.h in Headers */ = {isa = PBXBuildFile; fileRef = 9302B0BE0D79F82C00C7EE83 /* PageGroup.h */; settings = {ATTRIBUTES = (Private, ); }; };
9305B24D098F1B6B00C28855 /* Timer.h in Headers */ = {isa = PBXBuildFile; fileRef = 9305B24C098F1B6B00C28855 /* Timer.h */; settings = {ATTRIBUTES = (Private, ); }; };
930705D809E0C9B700B17FE4 /* JSCounter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 930705D709E0C9B700B17FE4 /* JSCounter.cpp */; };
930705DA09E0C9BF00B17FE4 /* JSCounter.h in Headers */ = {isa = PBXBuildFile; fileRef = 930705D909E0C9BF00B17FE4 /* JSCounter.h */; };
93F1999D08245E59001E9ABC /* DeprecatedValueList.h in Headers */ = {isa = PBXBuildFile; fileRef = F58786C202DE3B8601EA4122 /* DeprecatedValueList.h */; settings = {ATTRIBUTES = (Private, ); }; };
93F1999E08245E59001E9ABC /* DeprecatedValueListImpl.h in Headers */ = {isa = PBXBuildFile; fileRef = F587853B02DE375901EA4122 /* DeprecatedValueListImpl.h */; settings = {ATTRIBUTES = (Private, ); }; };
93F199A808245E59001E9ABC /* WebCoreFrameView.h in Headers */ = {isa = PBXBuildFile; fileRef = F587854C02DE375901EA4122 /* WebCoreFrameView.h */; settings = {ATTRIBUTES = (Private, ); }; };
- 93F199A908245E59001E9ABC /* WebCoreHistory.h in Headers */ = {isa = PBXBuildFile; fileRef = F5517DC2031AB56301A80180 /* WebCoreHistory.h */; settings = {ATTRIBUTES = (Private, ); }; };
93F199B308245E59001E9ABC /* WebCoreViewFactory.h in Headers */ = {isa = PBXBuildFile; fileRef = F587855402DE375901EA4122 /* WebCoreViewFactory.h */; settings = {ATTRIBUTES = (Private, ); }; };
93F199B808245E59001E9ABC /* ScrollBar.h in Headers */ = {isa = PBXBuildFile; fileRef = BC7B2AF80450824100A8000F /* ScrollBar.h */; settings = {ATTRIBUTES = (Private, ); }; };
93F199BB08245E59001E9ABC /* WebCoreKeyboardUIMode.h in Headers */ = {isa = PBXBuildFile; fileRef = BE983D95052A2E0A00892D85 /* WebCoreKeyboardUIMode.h */; settings = {ATTRIBUTES = (Private, ); }; };
93F19A9D08245E59001E9ABC /* TextResourceDecoder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F523D27802DE43D7018635CA /* TextResourceDecoder.cpp */; };
93F19AB908245E59001E9ABC /* Range.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F523D30302DE4476018635CA /* Range.cpp */; };
93F19ABC08245E59001E9ABC /* XMLTokenizer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F523D30902DE4476018635CA /* XMLTokenizer.cpp */; };
- 93F19AC808245E59001E9ABC /* WebCoreHistory.m in Sources */ = {isa = PBXBuildFile; fileRef = F5517DC3031AB56301A80180 /* WebCoreHistory.m */; };
93F19AD508245E59001E9ABC /* RenderTreeAsText.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 93955A4203D72932008635CE /* RenderTreeAsText.cpp */; };
93F19ADC08245E59001E9ABC /* PlatformScrollBarMac.mm in Sources */ = {isa = PBXBuildFile; fileRef = BC7B2AF90450824100A8000F /* PlatformScrollBarMac.mm */; };
93F19AE108245E59001E9ABC /* BlockExceptions.mm in Sources */ = {isa = PBXBuildFile; fileRef = 65F80697054D9F86008BF776 /* BlockExceptions.mm */; };
1AE82FEB0CAB07EE002237AE /* JSSQLResultSet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSSQLResultSet.h; sourceTree = "<group>"; };
1AE830420CAB0ED1002237AE /* JSDatabaseCustom.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSDatabaseCustom.cpp; sourceTree = "<group>"; };
1AF326400D78B5530068F0C4 /* AXObjectCacheMac.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = AXObjectCacheMac.mm; sourceTree = "<group>"; };
- 1AF326410D78B5530068F0C4 /* GlobalHistoryMac.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = GlobalHistoryMac.mm; sourceTree = "<group>"; };
1AF326420D78B5530068F0C4 /* WebCoreAXObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebCoreAXObject.h; sourceTree = "<group>"; };
1AF326430D78B5530068F0C4 /* WebCoreAXObject.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = WebCoreAXObject.mm; sourceTree = "<group>"; };
1AF326760D78B9440068F0C4 /* AXObjectCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AXObjectCache.h; sourceTree = "<group>"; };
1AF326770D78B9440068F0C4 /* EditorClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EditorClient.h; sourceTree = "<group>"; };
- 1AF3267A0D78B94E0068F0C4 /* GlobalHistory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GlobalHistory.h; sourceTree = "<group>"; };
1AFE117B0CBFFB36003017FA /* SQLResultSetRowList.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SQLResultSetRowList.cpp; sourceTree = "<group>"; };
1AFE117C0CBFFB36003017FA /* SQLResultSetRowList.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SQLResultSetRowList.h; sourceTree = "<group>"; };
1AFE118C0CBFFC4E003017FA /* SQLResultSetRowList.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = SQLResultSetRowList.idl; sourceTree = "<group>"; };
85FF31580AAFBFCB00374F38 /* DOMKeyboardEvent.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = DOMKeyboardEvent.h; sourceTree = "<group>"; };
85FF31590AAFBFCB00374F38 /* DOMKeyboardEvent.mm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.objcpp; path = DOMKeyboardEvent.mm; sourceTree = "<group>"; };
929264760B61FC7200B41D34 /* JSDocumentCustom.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = JSDocumentCustom.cpp; sourceTree = "<group>"; };
+ 9302B0BC0D79F82900C7EE83 /* PageGroup.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PageGroup.cpp; sourceTree = "<group>"; };
+ 9302B0BE0D79F82C00C7EE83 /* PageGroup.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PageGroup.h; sourceTree = "<group>"; };
9305B24C098F1B6B00C28855 /* Timer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Timer.h; sourceTree = "<group>"; };
9307059009E0C75800B17FE4 /* CSSPrimitiveValue.idl */ = {isa = PBXFileReference; explicitFileType = sourcecode; fileEncoding = 4; path = CSSPrimitiveValue.idl; sourceTree = "<group>"; };
930705C709E0C95F00B17FE4 /* Counter.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = Counter.idl; sourceTree = "<group>"; };
F523D30402DE4476018635CA /* Range.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = Range.h; sourceTree = "<group>"; tabWidth = 8; usesTabs = 0; };
F523D30902DE4476018635CA /* XMLTokenizer.cpp */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.cpp.cpp; path = XMLTokenizer.cpp; sourceTree = "<group>"; tabWidth = 8; usesTabs = 0; };
F523D30A02DE4476018635CA /* XMLTokenizer.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = XMLTokenizer.h; sourceTree = "<group>"; tabWidth = 8; usesTabs = 0; };
- F5517DC2031AB56301A80180 /* WebCoreHistory.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = WebCoreHistory.h; sourceTree = "<group>"; };
- F5517DC3031AB56301A80180 /* WebCoreHistory.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; path = WebCoreHistory.m; sourceTree = "<group>"; };
F58784F002DE375901EA4122 /* CursorMac.mm */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = CursorMac.mm; sourceTree = "<group>"; tabWidth = 8; usesTabs = 0; };
F587851502DE375901EA4122 /* DeprecatedPtrListImpl.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = DeprecatedPtrListImpl.h; sourceTree = "<group>"; tabWidth = 8; usesTabs = 0; };
F587851602DE375901EA4122 /* DeprecatedPtrListImpl.cpp */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DeprecatedPtrListImpl.cpp; sourceTree = "<group>"; tabWidth = 8; usesTabs = 0; };
84B2B24F056BF15F00D2B771 /* SSLKeyGeneratorMac.mm */,
6582A15509999D6D00BEEB6D /* SystemTimeMac.cpp */,
51DF6D7F0B92A18E00C2DC85 /* ThreadCheck.mm */,
- F5517DC2031AB56301A80180 /* WebCoreHistory.h */,
- F5517DC3031AB56301A80180 /* WebCoreHistory.m */,
84B2B1F7056BEF3A00D2B771 /* WebCoreKeyGenerator.h */,
84B2B1F8056BEF3A00D2B771 /* WebCoreKeyGenerator.m */,
934D9BA60B8C1175007B42A9 /* WebCoreNSStringExtras.h */,
65A21483097A3F5300B9050A /* FrameTree.h */,
65CBFEF70974F607001DAC25 /* FrameView.cpp */,
65CBFEF80974F607001DAC25 /* FrameView.h */,
- 1AF3267A0D78B94E0068F0C4 /* GlobalHistory.h */,
BC94D1500C275C8B006BC617 /* History.cpp */,
BC94D1510C275C8B006BC617 /* History.h */,
BC94D1520C275C8B006BC617 /* History.idl */,
935C476209AC4CE600A6AAB4 /* MouseEventWithHitTestResults.h */,
65FEA86809833ADE00BED4AB /* Page.cpp */,
65A21467097A329100B9050A /* Page.h */,
+ 9302B0BC0D79F82900C7EE83 /* PageGroup.cpp */,
+ 9302B0BE0D79F82C00C7EE83 /* PageGroup.h */,
65D1C1C909932B22000CB324 /* Plugin.h */,
BCEC01BA0C274DAC009F4EC9 /* Screen.cpp */,
BCEC01BB0C274DAC009F4EC9 /* Screen.h */,
isa = PBXGroup;
children = (
1AF326400D78B5530068F0C4 /* AXObjectCacheMac.mm */,
- 1AF326410D78B5530068F0C4 /* GlobalHistoryMac.mm */,
1AF326420D78B5530068F0C4 /* WebCoreAXObject.h */,
1AF326430D78B5530068F0C4 /* WebCoreAXObject.mm */,
ABAF22070C03B1C700B0BCF0 /* ChromeMac.mm */,
B255996F0D00D8BA00BB825C /* WKTableTransferFilter.h in Headers */,
654EC611097778F500DAB52C /* WebCoreFrameBridge.h in Headers */,
93F199A808245E59001E9ABC /* WebCoreFrameView.h in Headers */,
- 93F199A908245E59001E9ABC /* WebCoreHistory.h in Headers */,
93F199C208245E59001E9ABC /* WebCoreKeyGenerator.h in Headers */,
93F199BB08245E59001E9ABC /* WebCoreKeyboardUIMode.h in Headers */,
934D9BA70B8C1175007B42A9 /* WebCoreNSStringExtras.h in Headers */,
1CEFC9B90D78DC8C007D2579 /* SchedulePair.h in Headers */,
1AF326480D78B5530068F0C4 /* WebCoreAXObject.h in Headers */,
1AF326780D78B9440068F0C4 /* AXObjectCache.h in Headers */,
- 1AF3267B0D78B94E0068F0C4 /* GlobalHistory.h in Headers */,
+ 9302B0BF0D79F82C00C7EE83 /* PageGroup.h in Headers */,
BCA83E500D7CE1E9003421A8 /* JSClipboard.h in Headers */,
BC6C49F40D7DBA0500FFA558 /* JSImageConstructor.h in Headers */,
BC3452440D7E00EA0016574A /* JSRGBColor.h in Headers */,
B255996D0D00D8BA00BB825C /* WKSpotLightFilter.m in Sources */,
B25599700D00D8BA00BB825C /* WKTableTransferFilter.m in Sources */,
654EC612097778F500DAB52C /* WebCoreFrameBridge.mm in Sources */,
- 93F19AC808245E59001E9ABC /* WebCoreHistory.m in Sources */,
93F19AE508245E59001E9ABC /* WebCoreKeyGenerator.m in Sources */,
934D9BA50B8C116B007B42A9 /* WebCoreNSStringExtras.mm in Sources */,
DD05FE0E0B8BA3C6009ACDFE /* WebCoreObjCExtras.c in Sources */,
A766F3530D6BDE3500ABDDB3 /* JSCanvasPixelArrayCustom.cpp in Sources */,
1CEFC9BA0D78DC8C007D2579 /* SchedulePair.cpp in Sources */,
1AF326460D78B5530068F0C4 /* AXObjectCacheMac.mm in Sources */,
- 1AF326470D78B5530068F0C4 /* GlobalHistoryMac.mm in Sources */,
1AF326490D78B5530068F0C4 /* WebCoreAXObject.mm in Sources */,
+ 9302B0BD0D79F82900C7EE83 /* PageGroup.cpp in Sources */,
1CE24F970D7CAF0E007E04C2 /* SchedulePairMac.mm in Sources */,
BCA83E4F0D7CE1E9003421A8 /* JSClipboard.cpp in Sources */,
BCA83E520D7CE205003421A8 /* JSClipboardCustom.cpp in Sources */,
#include "FontValue.h"
#include "Frame.h"
#include "FrameView.h"
-#include "GlobalHistory.h"
#include "HTMLDocument.h"
#include "HTMLElement.h"
#include "HTMLInputElement.h"
#include "HTMLNames.h"
#include "MediaList.h"
#include "MediaQueryEvaluator.h"
+#include "Page.h"
+#include "PageGroup.h"
#include "Pair.h"
#include "Rect.h"
#include "RenderTheme.h"
CSSStyleSheet *CSSStyleSelector::m_svgSheet = 0;
#endif
-static CSSStyleSelector::EncodedURL* currentEncodedURL = 0;
static PseudoState pseudoState;
static const MediaQueryEvaluator& screenEval()
m_medium = 0;
}
-void CSSStyleSelector::setEncodedURL(const KURL& url)
-{
- KURL u = url;
-
- u.setQuery(String());
- u.setRef(String());
- m_encodedURL.file = u.string();
- int pos = m_encodedURL.file.reverseFind('/');
- m_encodedURL.path = m_encodedURL.file;
- if (pos > 0) {
- m_encodedURL.path.truncate(pos);
- m_encodedURL.path.append('/');
- }
- u.setPath(String());
- m_encodedURL.prefix = u.string();
-}
-
CSSStyleSelector::~CSSStyleSelector()
{
delete m_medium;
- ::delete m_rootDefaultStyle;
-
+ delete m_rootDefaultStyle;
delete m_authorStyle;
delete m_userStyle;
}
m_styledElement = static_cast<StyledElement*>(m_element);
else
m_styledElement = 0;
- currentEncodedURL = &m_encodedURL;
pseudoState = PseudoUnknown;
}
m_fontDirty = false;
}
-static inline int findSlashDotDotSlash(const UChar* characters, size_t length)
-{
- unsigned loopLimit = length < 4 ? 0 : length - 3;
- for (unsigned i = 0; i < loopLimit; ++i) {
- if (characters[i] == '/' && characters[i + 1] == '.' && characters[i + 2] == '.' && characters[i + 3] == '/')
- return i;
- }
- return -1;
-}
-
-static inline int findSlashSlash(const UChar* characters, size_t length, int position)
-{
- unsigned loopLimit = length < 2 ? 0 : length - 1;
- for (unsigned i = position; i < loopLimit; ++i) {
- if (characters[i] == '/' && characters[i + 1] == '/')
- return i;
- }
- return -1;
-}
-
-static inline int findSlashDotSlash(const UChar* characters, size_t length)
-{
- unsigned loopLimit = length < 3 ? 0 : length - 2;
- for (unsigned i = 0; i < loopLimit; ++i) {
- if (characters[i] == '/' && characters[i + 1] == '.' && characters[i + 2] == '/')
- return i;
- }
- return -1;
-}
-
-static inline bool containsColonSlashSlash(const UChar* characters, unsigned length)
-{
- unsigned loopLimit = length < 3 ? 0 : length - 2;
- for (unsigned i = 0; i < loopLimit; ++i)
- if (characters[i] == ':' && characters[i + 1] == '/' && characters[i + 2] == '/')
- return true;
- return false;
-}
-
-static void cleanPath(Vector<UChar, 512>& path)
-{
- int pos;
- while ((pos = findSlashDotDotSlash(path.data(), path.size())) != -1) {
- int prev = reverseFind(path.data(), path.size(), '/', pos - 1);
- // don't remove the host, i.e. http://foo.org/../foo.html
- if (prev < 0 || (prev > 3 && path[prev - 2] == ':' && path[prev - 1] == '/'))
- path.remove(pos, 3);
- else
- path.remove(prev, pos - prev + 3);
- }
-
- // Don't remove "//" from an anchor identifier. -rjw
- // Set refPos to -2 to mean "I haven't looked for the anchor yet".
- // We don't want to waste a function call on the search for the the anchor
- // in the vast majority of cases where there is no "//" in the path.
- pos = 0;
- int refPos = -2;
- while ((pos = findSlashSlash(path.data(), path.size(), pos)) != -1) {
- if (refPos == -2)
- refPos = find(path.data(), path.size(), '#');
- if (refPos > 0 && pos >= refPos)
- break;
-
- if (pos == 0 || path[pos - 1] != ':')
- path.remove(pos);
- else
- pos += 2;
- }
-
- // FIXME: We don't want to remove "/./" from an anchor identifier either.
- while ((pos = findSlashDotSlash(path.data(), path.size())) != -1)
- path.remove(pos, 2);
-}
-
-static void checkPseudoState(Element *e, bool checkVisited = true)
+static void checkPseudoState(Element* e, bool checkVisited = true)
{
if (!e->isLink()) {
pseudoState = PseudoNone;
return;
}
- const UChar* characters = attr->characters();
- unsigned length = attr->length();
+ Document* document = e->document();
- if (containsColonSlashSlash(characters, length)) {
- // FIXME: Strange to not clean the path just beacause it has "://" in it.
- pseudoState = historyContains(characters, length) ? PseudoVisited : PseudoLink;
+ Frame* frame = document->frame();
+ if (!frame) {
+ pseudoState = PseudoLink;
return;
}
- Vector<UChar, 512> buffer;
- if (length && characters[0] == '/') {
- buffer.append(currentEncodedURL->prefix.characters(), currentEncodedURL->prefix.length());
- } else if (length && characters[0] == '#') {
- buffer.append(currentEncodedURL->file.characters(), currentEncodedURL->file.length());
- } else {
- buffer.append(currentEncodedURL->path.characters(), currentEncodedURL->path.length());
+ Page* page = frame->page();
+ if (!page) {
+ pseudoState = PseudoLink;
+ return;
}
- buffer.append(characters, length);
- cleanPath(buffer);
- pseudoState = historyContains(buffer.data(), buffer.size()) ? PseudoVisited : PseudoLink;
+
+ pseudoState = page->group().isLinkVisited(document, *attr) ? PseudoVisited : PseudoLink;
}
// a helper function for parsing nth-arguments
mappedAttrsMatch = s->mappedAttributes()->mapsEquivalent(m_styledElement->mappedAttributes());
if (mappedAttrsMatch) {
bool linksMatch = true;
+
if (s->isLink()) {
// We need to check to see if the visited state matches.
- Color linkColor = m_element->document()->linkColor();
- Color visitedColor = m_element->document()->visitedLinkColor();
- if (pseudoState == PseudoUnknown)
+ if (pseudoState == PseudoUnknown) {
+ const Color& linkColor = m_element->document()->linkColor();
+ const Color& visitedColor = m_element->document()->visitedLinkColor();
checkPseudoState(m_element, style->pseudoState() != PseudoAnyLink || linkColor != visitedColor);
+ }
linksMatch = (pseudoState == style->pseudoState());
}
if (ident == CSS_VAL__WEBKIT_TEXT)
col = m_element->document()->textColor();
else if (ident == CSS_VAL__WEBKIT_LINK) {
- Color linkColor = m_element->document()->linkColor();
- Color visitedColor = m_element->document()->visitedLinkColor();
+ const Color& linkColor = m_element->document()->linkColor();
+ const Color& visitedColor = m_element->document()->visitedLinkColor();
if (linkColor == visitedColor)
col = linkColor;
else {
bool strictParsing;
- struct EncodedURL {
- String prefix; // protocol, host, etc.
- String path;
- String file;
- } m_encodedURL;
-
- void setEncodedURL(const KURL& url);
-
// Given a CSS keyword in the range (xx-small to -webkit-xxx-large), this function will return
// the correct font size scaled relative to the user's default (medium).
float fontSizeForKeyword(int keyword, bool quirksMode, bool monospace) const;
bool m_matchAuthorAndUserStyles;
RefPtr<CSSFontSelector> m_fontSelector;
-
HashSet<AtomicStringImpl*> m_selectorAttrs;
-
Vector<CSSMutableStyleDeclaration*> m_additionalAttributeStyleDecls;
-
Vector<MediaQueryResult*> m_viewportDependentMediaQueryResults;
void applyProperty(int id, CSSValue*);
if (Settings* docSettings = settings())
matchAuthorAndUserStyles = docSettings->authorAndUserStylesEnabled();
m_styleSelector = new CSSStyleSelector(this, userStyleSheet(), m_styleSheets.get(), m_mappedElementSheet.get(), !inCompatMode(), matchAuthorAndUserStyles);
- m_styleSelector->setEncodedURL(m_url);
}
recalcStyle(Force);
return;
m_url = url;
- if (m_styleSelector)
- m_styleSelector->setEncodedURL(url);
-
m_isAllowedToLoadLocalResources = shouldBeAllowedToLoadLocalResources();
}
// Create a new style selector
delete m_styleSelector;
m_styleSelector = new CSSStyleSelector(this, userStyleSheet(), m_styleSheets.get(), m_mappedElementSheet.get(), !inCompatMode(), matchAuthorAndUserStyles);
- m_styleSelector->setEncodedURL(m_url);
m_didCalculateStyleSelector = true;
}
#include "MainResourceLoader.h"
#include "Page.h"
#include "PageCache.h"
+#include "PageGroup.h"
#include "PluginInfoStore.h"
#include "ProgressTracker.h"
#include "RenderPart.h"
void FrameLoader::addBackForwardItemClippedAtTarget(bool doClip)
{
- if (Page* page = m_frame->page())
- if (!documentLoader()->urlForHistory().isEmpty()) {
- Frame* mainFrame = page->mainFrame();
- ASSERT(mainFrame);
- FrameLoader* frameLoader = mainFrame->loader();
-
- if (!frameLoader->m_didPerformFirstNavigation && page->backForwardList()->entries().size() == 1) {
- frameLoader->m_didPerformFirstNavigation = true;
- m_client->didPerformFirstNavigation();
- }
+ Page* page = m_frame->page();
+ if (!page)
+ return;
- RefPtr<HistoryItem> item = frameLoader->createHistoryItemTree(m_frame, doClip);
- LOG(BackForward, "WebCoreBackForward - Adding backforward item %p for frame %s", item.get(), documentLoader()->url().string().ascii().data());
- page->backForwardList()->addItem(item);
- }
+ if (documentLoader()->urlForHistory().isEmpty())
+ return;
+
+ Frame* mainFrame = page->mainFrame();
+ ASSERT(mainFrame);
+ FrameLoader* frameLoader = mainFrame->loader();
+
+ if (!frameLoader->m_didPerformFirstNavigation && page->backForwardList()->entries().size() == 1) {
+ frameLoader->m_didPerformFirstNavigation = true;
+ m_client->didPerformFirstNavigation();
+ }
+
+ RefPtr<HistoryItem> item = frameLoader->createHistoryItemTree(m_frame, doClip);
+ LOG(BackForward, "WebCoreBackForward - Adding backforward item %p for frame %s", item.get(), documentLoader()->url().string().ascii().data());
+ page->backForwardList()->addItem(item);
}
PassRefPtr<HistoryItem> FrameLoader::createHistoryItemTree(Frame* targetFrame, bool clipAtTarget)
// Walk the frame tree and ensure that the URLs match the URLs in the item.
bool FrameLoader::urlsMatchItem(HistoryItem* item) const
{
- KURL currentURL = documentLoader()->url();
-
+ const KURL& currentURL = documentLoader()->url();
if (!equalIgnoringRef(currentURL, item->url()))
return false;
-
+
const HistoryItemVector& childItems = item->children();
-
+
unsigned size = childItems.size();
for (unsigned i = 0; i < size; ++i) {
Frame* childFrame = m_frame->tree()->child(childItems[i]->target());
// <rdar://problem/3951283> can view pages from the back/forward cache that should be disallowed by Parental Controls
// Ultimately, history item navigations should go through the policy delegate. That's covered in:
// <rdar://problem/3979539> back/forward cache navigations should consult policy delegate
- if (Page* page = m_frame->page())
- if (m_client->shouldGoToHistoryItem(targetItem)) {
- BackForwardList* bfList = page->backForwardList();
- HistoryItem* currentItem = bfList->currentItem();
-
- // Set the BF cursor before commit, which lets the user quickly click back/forward again.
- // - plus, it only makes sense for the top level of the operation through the frametree,
- // as opposed to happening for some/one of the page commits that might happen soon
- bfList->goToItem(targetItem);
- recursiveGoToItem(targetItem, currentItem, type);
- }
+ Page* page = m_frame->page();
+ if (!page)
+ return;
+ if (!m_client->shouldGoToHistoryItem(targetItem))
+ return;
+
+ // Set the BF cursor before commit, which lets the user quickly click back/forward again.
+ // - plus, it only makes sense for the top level of the operation through the frametree,
+ // as opposed to happening for some/one of the page commits that might happen soon
+ BackForwardList* bfList = page->backForwardList();
+ HistoryItem* currentItem = bfList->currentItem();
+ bfList->goToItem(targetItem);
+ recursiveGoToItem(targetItem, currentItem, type);
}
// The general idea here is to traverse the frame tree and the item tree in parallel,
return true;
}
-void FrameLoader::updateGlobalHistory()
-{
- Settings* settings = m_frame->settings();
- if (!settings)
- return;
- if (settings->privateBrowsingEnabled())
- return;
- const KURL& url = documentLoader()->urlForHistory();
- if (url.isEmpty())
- return;
- m_client->updateGlobalHistory(url);
-}
+// There are 3 things you might think of as "history", all of which are handled by these functions.
+//
+// 1) Back/forward: The m_currentHistoryItem is part of this mechanism.
+// 2) Global history: Handled by the client.
+// 3) Visited links: Handled by the PageGroup.
void FrameLoader::updateHistoryForStandardLoad()
{
LOG(History, "WebCoreHistory: Updating History for Standard Load in frame %s", documentLoader()->url().string().ascii().data());
-
+
+ Settings* settings = m_frame->settings();
+ bool needPrivacy = !settings || settings->privateBrowsingEnabled();
+ const KURL& historyURL = documentLoader()->urlForHistory();
+
// If the navigation occured during load and this is a subframe, update the current
- // history item rather than adding a new one. <rdar://problem/5333496>
+ // back/forward item rather than adding a new one and don't add the new URL to global
+ // history at all. But do add it to visited links. <rdar://problem/5333496>
bool frameNavigationDuringLoad = false;
if (m_navigationDuringLoad) {
HTMLFrameOwnerElement* owner = m_frame->ownerElement();
}
if (!frameNavigationDuringLoad && !documentLoader()->isClientRedirect()) {
- if (!documentLoader()->urlForHistory().isEmpty())
+ if (!historyURL.isEmpty()) {
addBackForwardItemClippedAtTarget(true);
+ if (!needPrivacy)
+ m_client->updateGlobalHistory(historyURL);
+ }
} else if (documentLoader()->unreachableURL().isEmpty() && m_currentHistoryItem) {
m_currentHistoryItem->setURL(documentLoader()->url());
m_currentHistoryItem->setFormInfoFromRequest(documentLoader()->request());
}
- updateGlobalHistory();
+ if (!historyURL.isEmpty() && !needPrivacy) {
+ if (Page* page = m_frame->page())
+ page->group().addVisitedLink(historyURL);
+ }
}
void FrameLoader::updateHistoryForClientRedirect()
m_currentHistoryItem->clearScrollPoint();
}
- // FIXME: Should we call updateGlobalHistory here?
+ Settings* settings = m_frame->settings();
+ bool needPrivacy = !settings || settings->privateBrowsingEnabled();
+ const KURL& historyURL = documentLoader()->urlForHistory();
+
+ if (!historyURL.isEmpty() && !needPrivacy) {
+ if (Page* page = m_frame->page())
+ page->group().addVisitedLink(historyURL);
+ }
}
void FrameLoader::updateHistoryForBackForwardNavigation()
// Must grab the current scroll position before disturbing it
saveScrollPositionAndViewStateToItem(m_previousHistoryItem.get());
-
- // FIXME: Should we call updateGlobalHistory here?
}
void FrameLoader::updateHistoryForReload()
if (documentLoader()->unreachableURL().isEmpty())
m_currentHistoryItem->setURL(documentLoader()->requestURL());
}
-
- updateGlobalHistory();
}
void FrameLoader::updateHistoryForRedirectWithLockedHistory()
LOG(History, "WebCoreHistory: Updating History for internal load in frame %s", documentLoader()->title().utf8().data());
#endif
+ Settings* settings = m_frame->settings();
+ bool needPrivacy = !settings || settings->privateBrowsingEnabled();
+ const KURL& historyURL = documentLoader()->urlForHistory();
+
if (documentLoader()->isClientRedirect()) {
- if (!m_currentHistoryItem && !m_frame->tree()->parent())
+ if (!m_currentHistoryItem && !m_frame->tree()->parent()) {
addBackForwardItemClippedAtTarget(true);
+ if (!needPrivacy && !historyURL.isEmpty())
+ m_client->updateGlobalHistory(historyURL);
+ }
if (m_currentHistoryItem) {
m_currentHistoryItem->setURL(documentLoader()->url());
m_currentHistoryItem->setFormInfoFromRequest(documentLoader()->request());
parentFrame->loader()->m_currentHistoryItem->addChildItem(createHistoryItem(true));
}
- updateGlobalHistory();
+ if (!historyURL.isEmpty() && !needPrivacy) {
+ if (Page* page = m_frame->page())
+ page->group().addVisitedLink(historyURL);
+ }
}
void FrameLoader::updateHistoryForCommit()
void updateHistoryForClientRedirect();
void updateHistoryForCommit();
- void updateGlobalHistory();
-
void redirectionTimerFired(Timer<FrameLoader>*);
void checkCompletedTimerFired(Timer<FrameLoader>*);
void checkLoadCompleteTimerFired(Timer<FrameLoader>*);
#include "InspectorController.h"
#include "JSDOMWindow.h"
#include "Page.h"
+#include "PageGroup.h"
#include "PausedTimeouts.h"
#include "ResourceHandle.h"
#include "SecurityOrigin.h"
{
}
+void ChromeClient::populateVisitedLinks()
+{
+}
+
// --------
PageGroupLoadDeferrer::PageGroupLoadDeferrer(Page* page, bool deferSelf)
{
- const HashSet<Page*>* group = page->frameNamespace();
-
- if (!group)
- return;
+ const HashSet<Page*>& pages = page->group().pages();
- HashSet<Page*>::const_iterator end = group->end();
- for (HashSet<Page*>::const_iterator it = group->begin(); it != end; ++it) {
+ HashSet<Page*>::const_iterator end = pages.end();
+ for (HashSet<Page*>::const_iterator it = pages.begin(); it != end; ++it) {
Page* otherPage = *it;
if ((deferSelf || otherPage != page)) {
if (!otherPage->defersLoading())
virtual void dashboardRegionsChanged();
+ virtual void populateVisitedLinks();
+
protected:
virtual ~ChromeClient() { }
};
#include "Frame.h"
#include "Page.h"
+#include "PageGroup.h"
#include <stdarg.h>
#include <wtf/Platform.h>
#include <wtf/StringExtras.h>
if (frame->tree()->name() == name)
return frame;
- // Search the entire tree for all other pages in this namespace.
- const HashSet<Page*>* pages = page->frameNamespace();
- if (pages) {
- HashSet<Page*>::const_iterator end = pages->end();
- for (HashSet<Page*>::const_iterator it = pages->begin(); it != end; ++it) {
- Page* otherPage = *it;
- if (otherPage != page)
- for (Frame* frame = otherPage->mainFrame(); frame; frame = frame->tree()->traverseNext())
- if (frame->tree()->name() == name)
- return frame;
+ // Search the entire tree of each of the other pages in this namespace.
+ // FIXME: Is random order OK?
+ const HashSet<Page*>& pages = page->group().pages();
+ HashSet<Page*>::const_iterator end = pages.end();
+ for (HashSet<Page*>::const_iterator it = pages.begin(); it != end; ++it) {
+ Page* otherPage = *it;
+ if (otherPage != page) {
+ for (Frame* frame = otherPage->mainFrame(); frame; frame = frame->tree()->traverseNext()) {
+ if (frame->tree()->name() == name)
+ return frame;
+ }
}
}
#include "HistoryItem.h"
#include "InspectorController.h"
#include "Logging.h"
+#include "PageGroup.h"
#include "ProgressTracker.h"
#include "RenderWidget.h"
#include "SelectionController.h"
namespace WebCore {
+typedef HashMap<String, PageGroup*> PageGroupMap;
+
static HashSet<Page*>* allPages;
-static HashMap<String, HashSet<Page*>*>* frameNamespaces;
+static PageGroupMap* pageGroups;
#ifndef NDEBUG
WTFLogChannel LogWebCorePageLeaks = { 0x00000000, "", WTFLogChannelOn };
, m_parentInspectorController(0)
, m_didLoadUserStyleSheet(false)
, m_userStyleSheetModificationTime(0)
+ , m_group(0)
, m_debugger(0)
{
if (!allPages) {
void Page::setGroupName(const String& name)
{
- if (frameNamespaces && !m_groupName.isEmpty()) {
- HashSet<Page*>* oldNamespace = frameNamespaces->get(m_groupName);
- if (oldNamespace) {
- oldNamespace->remove(this);
- if (oldNamespace->isEmpty()) {
- frameNamespaces->remove(m_groupName);
- delete oldNamespace;
- }
- }
+ if (!m_groupName.isEmpty()) {
+ ASSERT(!m_singlePageGroup);
+ ASSERT(m_group);
+ ASSERT(pageGroups);
+ ASSERT(pageGroups->get(m_groupName) == m_group);
+ m_group->removePage(this);
+ if (m_group->pages().isEmpty())
+ pageGroups->remove(m_groupName);
}
m_groupName = name;
- if (!name.isEmpty()) {
- if (!frameNamespaces)
- frameNamespaces = new HashMap<String, HashSet<Page*>*>;
- HashSet<Page*>* newNamespace = frameNamespaces->get(name);
- if (!newNamespace) {
- newNamespace = new HashSet<Page*>;
- frameNamespaces->add(name, newNamespace);
+ if (name.isEmpty())
+ m_group = 0;
+ else {
+ m_singlePageGroup.clear();
+ if (!pageGroups)
+ pageGroups = new PageGroupMap;
+ pair<PageGroupMap::iterator, bool> result = pageGroups->add(name, 0);
+ if (!result.second) {
+ ASSERT(result.first->second);
+ m_group = result.first->second;
+ m_group->addPage(this);
+ } else {
+ ASSERT(!result.first->second);
+ m_group = new PageGroup(this);
+ result.first->second = m_group;
}
- newNamespace->add(this);
}
}
-const HashSet<Page*>* Page::frameNamespace() const
-{
- return (frameNamespaces && !m_groupName.isEmpty()) ? frameNamespaces->get(m_groupName) : 0;
-}
-
-const HashSet<Page*>* Page::frameNamespace(const String& groupName)
+void Page::initGroup()
{
- return (frameNamespaces && !groupName.isEmpty()) ? frameNamespaces->get(groupName) : 0;
+ ASSERT(!m_singlePageGroup);
+ ASSERT(!m_group);
+ m_singlePageGroup.set(new PageGroup(this));
+ m_group = m_singlePageGroup.get();
}
void Page::setNeedsReapplyStyles()
return m_userStyleSheet;
}
+void Page::removeAllVisitedLinks()
+{
+ if (!allPages)
+ return;
+ HashSet<PageGroup*> groups;
+ HashSet<Page*>::iterator pagesEnd = allPages->end();
+ for (HashSet<Page*>::iterator it = allPages->begin(); it != pagesEnd; ++it) {
+ if (PageGroup* group = (*it)->groupPtr())
+ groups.add(group);
+ }
+ HashSet<PageGroup*>::iterator groupsEnd = groups.end();
+ for (HashSet<PageGroup*>::iterator it = groups.begin(); it != groupsEnd; ++it)
+ (*it)->removeVisitedLinks();
+}
+
void Page::setDebuggerForAllPages(KJS::Debugger* debugger)
{
ASSERT(allPages);
// -*- mode: c++; c-basic-offset: 4 -*-
/*
- * Copyright (C) 2006 Apple Computer, Inc.
+ * Copyright (C) 2006, 2008 Apple Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
class Debugger;
}
-typedef enum TextCaseSensitivity {
- TextCaseSensitive,
- TextCaseInsensitive
-};
-
-typedef enum FindDirection {
- FindDirectionForward,
- FindDirectionBackward
-};
-
namespace WebCore {
class Chrome;
class ChromeClient;
class ContextMenuClient;
class ContextMenuController;
+ class Document;
class DragClient;
class DragController;
class EditorClient;
class InspectorClient;
class InspectorController;
class Node;
+ class PageGroup;
class ProgressTracker;
class Selection;
class SelectionController;
class Settings;
+ class KURL;
+
+ enum TextCaseSensitivity { TextCaseSensitive, TextCaseInsensitive };
+ enum FindDirection { FindDirectionForward, FindDirectionBackward };
class Page : Noncopyable {
public:
static void setNeedsReapplyStyles();
- static const HashSet<Page*>* frameNamespace(const String&);
Page(ChromeClient*, ContextMenuClient*, EditorClient*, DragClient*, InspectorClient*);
~Page();
void goToItem(HistoryItem*, FrameLoadType);
void setGroupName(const String&);
- String groupName() const { return m_groupName; }
+ const String& groupName() const { return m_groupName; }
- const HashSet<Page*>* frameNamespace() const;
+ PageGroup& group() { if (!m_group) initGroup(); return *m_group; }
+ PageGroup* groupPtr() { return m_group; } // can return 0
void incrementFrameCount() { ++m_frameCount; }
void decrementFrameCount() { --m_frameCount; }
static HINSTANCE instanceHandle() { return s_instanceHandle; }
#endif
+ static void removeAllVisitedLinks();
+
private:
+ void initGroup();
+
OwnPtr<Chrome> m_chrome;
OwnPtr<SelectionController> m_dragCaretController;
OwnPtr<DragController> m_dragController;
mutable bool m_didLoadUserStyleSheet;
mutable time_t m_userStyleSheetModificationTime;
+ OwnPtr<PageGroup> m_singlePageGroup;
+ PageGroup* m_group;
+
KJS::Debugger* m_debugger;
#if PLATFORM(WIN) || (PLATFORM(WX) && defined(__WXMSW__))
--- /dev/null
+/*
+ * Copyright (C) 2008 Apple Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "PageGroup.h"
+
+#include "ChromeClient.h"
+#include "Document.h"
+#include "Page.h"
+
+namespace WebCore {
+
+// --------
+
+PageGroup::PageGroup(Page* page)
+ : m_visitedLinksPopulated(false)
+{
+ ASSERT(page);
+ m_pages.add(page);
+}
+
+void PageGroup::addPage(Page* page)
+{
+ ASSERT(page);
+ ASSERT(!m_pages.contains(page));
+ m_pages.add(page);
+}
+
+void PageGroup::removePage(Page* page)
+{
+ ASSERT(page);
+ ASSERT(m_pages.contains(page));
+ m_pages.remove(page);
+}
+
+static inline int findSlashDotDotSlash(const UChar* characters, size_t length)
+{
+ if (length < 4)
+ return -1;
+ unsigned loopLimit = length - 3;
+ for (unsigned i = 0; i < loopLimit; ++i) {
+ if (characters[i] == '/' && characters[i + 1] == '.' && characters[i + 2] == '.' && characters[i + 3] == '/')
+ return i;
+ }
+ return -1;
+}
+
+static inline int findSlashSlash(const UChar* characters, size_t length, int position)
+{
+ if (length < 2)
+ return -1;
+ unsigned loopLimit = length - 1;
+ for (unsigned i = position; i < loopLimit; ++i) {
+ if (characters[i] == '/' && characters[i + 1] == '/')
+ return i;
+ }
+ return -1;
+}
+
+static inline int findSlashDotSlash(const UChar* characters, size_t length)
+{
+ if (length < 3)
+ return -1;
+ unsigned loopLimit = length - 2;
+ for (unsigned i = 0; i < loopLimit; ++i) {
+ if (characters[i] == '/' && characters[i + 1] == '.' && characters[i + 2] == '/')
+ return i;
+ }
+ return -1;
+}
+
+static inline bool containsColonSlashSlash(const UChar* characters, unsigned length)
+{
+ if (length < 3)
+ return false;
+ unsigned loopLimit = length - 2;
+ for (unsigned i = 0; i < loopLimit; ++i) {
+ if (characters[i] == ':' && characters[i + 1] == '/' && characters[i + 2] == '/')
+ return true;
+ }
+ return false;
+}
+
+static inline void cleanPath(Vector<UChar, 512>& path)
+{
+ // FIXME: Shold not do this in the query or anchor part.
+ int pos;
+ while ((pos = findSlashDotDotSlash(path.data(), path.size())) != -1) {
+ int prev = reverseFind(path.data(), path.size(), '/', pos - 1);
+ // don't remove the host, i.e. http://foo.org/../foo.html
+ if (prev < 0 || (prev > 3 && path[prev - 2] == ':' && path[prev - 1] == '/'))
+ path.remove(pos, 3);
+ else
+ path.remove(prev, pos - prev + 3);
+ }
+
+ // FIXME: Shold not do this in the query part.
+ // Set refPos to -2 to mean "I haven't looked for the anchor yet".
+ // We don't want to waste a function call on the search for the the anchor
+ // in the vast majority of cases where there is no "//" in the path.
+ pos = 0;
+ int refPos = -2;
+ while ((pos = findSlashSlash(path.data(), path.size(), pos)) != -1) {
+ if (refPos == -2)
+ refPos = find(path.data(), path.size(), '#');
+ if (refPos > 0 && pos >= refPos)
+ break;
+
+ if (pos == 0 || path[pos - 1] != ':')
+ path.remove(pos);
+ else
+ pos += 2;
+ }
+
+ // FIXME: Shold not do this in the query or anchor part.
+ while ((pos = findSlashDotSlash(path.data(), path.size())) != -1)
+ path.remove(pos, 2);
+}
+
+static inline bool matchLetter(UChar c, UChar lowercaseLetter)
+{
+ return (c | 0x20) == lowercaseLetter;
+}
+
+static inline bool needsTrailingSlash(const UChar* characters, unsigned length)
+{
+ if (length < 6)
+ return false;
+ if (!matchLetter(characters[0], 'h')
+ || !matchLetter(characters[1], 't')
+ || !matchLetter(characters[2], 't')
+ || !matchLetter(characters[3], 'p'))
+ return false;
+ if (!(characters[4] == ':'
+ || (matchLetter(characters[4], 's') && characters[5] == ':')))
+ return false;
+
+ unsigned pos = characters[4] == ':' ? 5 : 6;
+
+ // Skip initial two slashes if present.
+ if (pos + 1 < length && characters[pos] == '/' && characters[pos + 1] == '/')
+ pos += 2;
+
+ // Find next slash.
+ while (pos < length && characters[pos] != '/')
+ ++pos;
+
+ return pos == length;
+}
+
+bool PageGroup::isLinkVisited(Document* document, const AtomicString& attributeURL)
+{
+ if (!m_visitedLinksPopulated) {
+ m_visitedLinksPopulated = true;
+ ASSERT(!m_pages.isEmpty());
+ (*m_pages.begin())->chrome()->client()->populateVisitedLinks();
+ }
+
+ const UChar* characters = attributeURL.characters();
+ unsigned length = attributeURL.length();
+ if (!length)
+ return false;
+
+ // FIXME: It is strange that we do not do further processing on strings that have "://" in them.
+ // That's clearly incorrect for at least these reasons:
+ // 1) The "://" could be in the query or anchor.
+ // 2) The URL's path could have a "/./" or a "/../" or a "//" sequence in it.
+
+ // FIXME: needsTrailingSlash does not properly return true for a URL that has no path, but does
+ // have a query or anchor.
+
+ bool hasColonSlashSlash = containsColonSlashSlash(characters, length);
+
+ if (hasColonSlashSlash && !needsTrailingSlash(characters, length))
+ return m_visitedLinkHashes.contains(StringImpl::computeHash(characters, length));
+
+ Vector<UChar, 512> buffer;
+
+ // This is a poor man's completeURL. Faster with less memory allocation.
+ // FIXME: It's missing a lot of what completeURL does and what KURL does.
+ // FIXME: Move this into KURL? Or Document? Even the fast version should be in the right place,
+ // rather than here.
+
+ if (hasColonSlashSlash) {
+ // FIXME: This is incorrect for URLs that have a query or anchor; the "/" needs to go at the
+ // end of the path, *before* the query or anchor.
+ buffer.append(characters, length);
+ buffer.append('/');
+ return m_visitedLinkHashes.contains(StringImpl::computeHash(buffer.data(), buffer.size()));
+ }
+
+ const KURL& baseURL = document->baseURL();
+ switch (characters[0]) {
+ case '/':
+ buffer.append(baseURL.string().characters(), baseURL.pathStart());
+ break;
+ case '#':
+ buffer.append(baseURL.string().characters(), baseURL.pathEnd());
+ break;
+ default:
+ buffer.append(baseURL.string().characters(), baseURL.pathAfterLastSlash());
+ break;
+ }
+ buffer.append(characters, length);
+ cleanPath(buffer);
+ if (needsTrailingSlash(buffer.data(), buffer.size())) {
+ // FIXME: This is incorrect for URLs that have a query or anchor; the "/" needs to go at the
+ // end of the path, *before* the query or anchor.
+ buffer.append('/');
+ }
+
+ return m_visitedLinkHashes.contains(StringImpl::computeHash(buffer.data(), buffer.size()));
+}
+
+void PageGroup::addVisitedLink(const KURL& url)
+{
+ ASSERT(!url.isEmpty());
+ m_visitedLinkHashes.add(url.string().impl()->hash());
+}
+
+void PageGroup::addVisitedLink(const UChar* characters, size_t length)
+{
+ m_visitedLinkHashes.add(StringImpl::computeHash(characters, length));
+}
+
+void PageGroup::removeVisitedLinks()
+{
+ m_visitedLinkHashes.clear();
+}
+
+void PageGroup::removeAllVisitedLinks()
+{
+ Page::removeAllVisitedLinks();
+}
+
+} // namespace WebCore
/*
- * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
+ * Copyright (C) 2008 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef GlobalHistory_h
-#define GlobalHistory_h
+#ifndef PageGroup_h
+#define PageGroup_h
+#include <wtf/HashSet.h>
+#include <wtf/Noncopyable.h>
#include <wtf/unicode/Unicode.h>
namespace WebCore {
- bool historyContains(const UChar* characters, unsigned length);
+ class AtomicString;
+ class Document;
+ class KURL;
+ class Page;
-} // namespace WebCore
+ class PageGroup : Noncopyable {
+ public:
+ PageGroup(Page*);
+
+ const HashSet<Page*>& pages() const { return m_pages; }
+
+ void addPage(Page*);
+ void removePage(Page*);
+
+ bool isLinkVisited(Document*, const AtomicString& attributeValue);
-#endif // GlobalHistory_h
+ void addVisitedLink(const KURL&);
+ void addVisitedLink(const UChar*, size_t);
+ void removeVisitedLinks();
+ static void removeAllVisitedLinks();
+
+ private:
+ HashSet<Page*> m_pages;
+ HashSet<unsigned> m_visitedLinkHashes;
+ bool m_visitedLinksPopulated;
+ };
+
+} // namespace WebCore
+
+#endif // PageGroup_h
+++ /dev/null
-/*
- * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#import "config.h"
-#import "GlobalHistory.h"
-
-#import "WebCoreHistory.h"
-
-namespace WebCore {
-
-bool historyContains(const UChar* characters, unsigned length)
-{
- // the other side of the bridge is careful not to throw exceptions here
- return [[WebCoreHistory historyProvider] containsURL:characters length:length];
-}
-
-} // namespace WebCore
+++ /dev/null
-/*
- * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "GlobalHistory.h"
-
-#include "WebCoreHistory.h"
-
-namespace WebCore {
-
-bool historyContains(const UChar* characters, unsigned length)
-{
- WebCoreHistoryProvider* provider = WebCoreHistory::historyProvider();
- return provider && provider->containsURL(characters, length);
-}
-
-} // namespace WebCore
#include "Editor.h"
#include "FrameView.h"
#include "FTPDirectoryDocument.h"
-#include "GlobalHistory.h"
#include "KURL.h"
#include "NotImplemented.h"
#include "PluginDatabase.h"
/* Completely empty stubs (mostly to allow DRT to run): */
/********************************************************/
-bool WebCore::historyContains(const UChar*, unsigned) { return false; }
-
PluginSet PluginDatabase::getPluginsInPaths() const { notImplemented(); return PluginSet(); }
Vector<String> PluginDatabase::defaultPluginPaths() { notImplemented(); return Vector<String>(); }
bool PluginDatabase::isPreferredPluginPath(const String&) { notImplemented(); return false; }
+++ /dev/null
-/*
- * Copyright (C) 2003, 2007 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-@protocol WebCoreHistoryProvider <NSObject>
-- (BOOL)containsURL:(const UniChar*)unicode length:(unsigned)length;
-@end
-
-@interface WebCoreHistory : NSObject
-
-+ (void)setHistoryProvider:(id<WebCoreHistoryProvider>)h;
-+ (id<WebCoreHistoryProvider>)historyProvider;
-
-@end
+++ /dev/null
-/*
- * Copyright (C) 2003 Apple Computer, Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#import "config.h"
-
-#import "WebCoreHistory.h"
-
-@implementation WebCoreHistory
-
-static id<WebCoreHistoryProvider> _historyProvider = nil;
-
-+ (void)setHistoryProvider: (id<WebCoreHistoryProvider>)h
-{
- if (_historyProvider != h){
- [_historyProvider release];
- _historyProvider = [h retain];
- }
-}
-
-+ (id<WebCoreHistoryProvider>)historyProvider
-{
- return _historyProvider;
-}
-
-@end
#include "FileSystem.h"
#include "FrameView.h"
#include "GraphicsContext.h"
-#include "GlobalHistory.h"
#include "IconLoader.h"
#include "IntPoint.h"
#include "KURL.h"
+++ /dev/null
-/*
- * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "WebCoreHistory.h"
-
-namespace WebCore {
-
-static WebCoreHistoryProvider* _historyProvider = 0;
-
-void WebCoreHistory::setHistoryProvider(WebCoreHistoryProvider* h)
-{
- if (_historyProvider == h)
- return;
-
- delete _historyProvider;
- _historyProvider = h;
-}
-
-WebCoreHistoryProvider* WebCoreHistory::historyProvider()
-{
- return _historyProvider;
-}
-
-}
+++ /dev/null
-/*
-* Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
-*
-* Redistribution and use in source and binary forms, with or without
-* modification, are permitted provided that the following conditions
-* are met:
-* 1. Redistributions of source code must retain the above copyright
-* notice, this list of conditions and the following disclaimer.
-* 2. Redistributions in binary form must reproduce the above copyright
-* notice, this list of conditions and the following disclaimer in the
-* documentation and/or other materials provided with the distribution.
-*
-* THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
-* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
-* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
-* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
-* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#ifndef WEBCORE_HISTORY_H_
-#define WEBCORE_HISTORY_H_
-
-#include <unicode/umachine.h>
-
-namespace WebCore {
-
-class WebCoreHistoryProvider {
-public:
- virtual bool containsURL(const UChar* unicode, unsigned length) = 0;
-};
-
-class WebCoreHistory {
-public:
- static void setHistoryProvider(WebCoreHistoryProvider*);
- static WebCoreHistoryProvider* historyProvider();
-};
-
-}
-
-#endif
static WebCore::Cursor localCursor;
const WebCore::Cursor& WebCore::moveCursor() { return localCursor; }
-namespace WebCore {
- bool historyContains(const UChar*, unsigned) { return false; }
-}
-
void WebCore::findWordBoundary(UChar const* str,int len,int position,int* start, int* end) { notImplemented(); *start=position; *end=position; }
PluginSet PluginDatabase::getPluginsInPaths() const { notImplemented(); return PluginSet(); }
+2008-03-06 Darin Adler <darin@apple.com>
+
+ * WebKit.xcodeproj/project.pbxproj: Added WebHistoryInternal.h.
+
2008-03-06 David D. Kilzer <ddkilzer@apple.com>
Name the WebKit build phase script that generates WebKit.LP64.exp.
9398112F0824BF01008DF038 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 830E81E005853AC000AD0891 /* Security.framework */; };
93EB178D09F88D460091F8FF /* WebSystemInterface.m in Sources */ = {isa = PBXBuildFile; fileRef = 93EB178C09F88D460091F8FF /* WebSystemInterface.m */; };
93EB178F09F88D510091F8FF /* WebSystemInterface.h in Headers */ = {isa = PBXBuildFile; fileRef = 93EB178E09F88D510091F8FF /* WebSystemInterface.h */; };
+ 93FDE9330D79CAF30074F029 /* WebHistoryInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 93FDE9320D79CAF30074F029 /* WebHistoryInternal.h */; };
A70936AF0B5608DC00CDB48E /* WebDragClient.h in Headers */ = {isa = PBXBuildFile; fileRef = A70936AD0B5608DC00CDB48E /* WebDragClient.h */; };
A70936B00B5608DC00CDB48E /* WebDragClient.mm in Sources */ = {isa = PBXBuildFile; fileRef = A70936AE0B5608DC00CDB48E /* WebDragClient.mm */; };
A7D3C5BC0B5773C5002CA450 /* WebPasteboardHelper.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D3C5BA0B5773C5002CA450 /* WebPasteboardHelper.h */; };
93D623DD051E791F002F47DD /* libicucore.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libicucore.dylib; path = /usr/lib/libicucore.dylib; sourceTree = "<absolute>"; };
93EB178C09F88D460091F8FF /* WebSystemInterface.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = WebSystemInterface.m; sourceTree = "<group>"; };
93EB178E09F88D510091F8FF /* WebSystemInterface.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebSystemInterface.h; sourceTree = "<group>"; };
+ 93FDE9320D79CAF30074F029 /* WebHistoryInternal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebHistoryInternal.h; sourceTree = "<group>"; };
9CAE9D070252A4130ECA16EA /* WebPreferencesPrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = WebPreferencesPrivate.h; sourceTree = "<group>"; tabWidth = 8; usesTabs = 0; };
9CE1F8A302A5C6F30ECA2ACD /* WebImageRendererFactory.m */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 4; lastKnownFileType = sourcecode.c.objc; path = WebImageRendererFactory.m; sourceTree = "<group>"; tabWidth = 8; usesTabs = 0; };
9CF0E249021361B00ECA16EA /* WebFramePrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = WebFramePrivate.h; sourceTree = "<group>"; tabWidth = 8; usesTabs = 0; };
22F219CB08D236730030E078 /* WebBackForwardListPrivate.h */,
65DA2608052CC18700A97B31 /* WebHistory.mm */,
F520FB190221DEFD01C1A525 /* WebHistory.h */,
+ 93FDE9320D79CAF30074F029 /* WebHistoryInternal.h */,
3944607F020F50ED0ECA1767 /* WebHistoryItem.h */,
39446080020F50ED0ECA1767 /* WebHistoryItem.mm */,
516F296F03A6C45A00CA2D3A /* WebHistoryItemInternal.h */,
9398109B0824BF01008DF038 /* WebViewInternal.h in Headers */,
939810710824BF01008DF038 /* WebViewPrivate.h in Headers */,
939810970824BF01008DF038 /* npfunctions.h in Headers */,
+ 93FDE9330D79CAF30074F029 /* WebHistoryInternal.h in Headers */,
C0167BF80D7F5DD00028696E /* WebScriptDebugger.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
+2008-03-06 Darin Adler <darin@apple.com>
+
+ Reviewed by Mitz.
+
+ - fix http://bugs.webkit.org/show_bug.cgi?id=17526
+ REGRESSION: iframes are added to Safari's History menu
+ by separating the visited link machinery from global history
+
+ * History/WebHistory.mm: Moved WebHistoryPrivate inside this file.
+ (-[WebHistoryPrivate removeItemFromDateCaches:]): Removed the underscore from this
+ method name, since it's on a private object.
+ (-[WebHistoryPrivate removeItemForURLString:]): Added a call to the
+ PageGroup::removeAllVisitedLinks function if the last URL was removed.
+ (-[WebHistoryPrivate addItemToDateCaches:]): Removed the underscore from this
+ method name, since it's on a private object.
+ (-[WebHistoryPrivate removeAllItems]): Call PageGroup::removeAllVisitedLinks.
+ (-[WebHistoryPrivate ageLimitDate]): Removed the underscore from this
+ method name, since it's on a private object.
+ (-[WebHistoryPrivate loadHistoryGutsFromURL:savedItemsCount:collectDiscardedItemsInto:error:]):
+ Ditto.
+ (-[WebHistoryPrivate saveHistoryGuts:URL:error:]): Ditto. Also changed this
+ to correctly return the error by using the newer version of writeToURL: and
+ removed the FIXME about that.
+ (-[WebHistoryPrivate addVisitedLinksToPageGroup:]): Added. Calls addVisitedLink
+ for every link in the history.
+ (-[WebHistory saveToURL:error:]): Removed the FIXME, since we do get the error now.
+ (-[WebHistory addItem:]): Moved into the WebPrivate category.
+ (-[WebHistory addItemForURL:]): Ditto.
+ (-[WebHistory _addItemForURL:title:]): Added. Used for the normal case where we
+ create an item and already know its title.
+ (-[WebHistory ageLimitDate]): Moved into the WebPrivate category.
+ (-[WebHistory containsItemForURLString:]): Ditto.
+ (-[WebHistory removeItem:]): Ditto.
+ (-[WebHistory setLastVisitedTimeInterval:forItem:]): Ditto.
+ (-[WebHistory _itemForURLString:]): Ditto.
+ (-[WebHistory _addVisitedLinksToPageGroup:]): Added. For use only inside WebKit.
+
+ * History/WebHistoryInternal.h: Added.
+ * History/WebHistoryItemInternal.h: Tweaked formatting and includes.
+ * History/WebHistoryPrivate.h: Moved the WebHistoryPrivate class out of this header.
+ Also reorganized what was left behind.
+
+ * WebCoreSupport/WebChromeClient.h: Added populateVisitedLinks.
+ * WebCoreSupport/WebChromeClient.mm:
+ (WebChromeClient::populateVisitedLinks): Added a call to the new
+ -[WebHistory _addVisitedLinksToPageGroup:] method.
+
+ * WebCoreSupport/WebFrameLoaderClient.mm:
+ (WebFrameLoaderClient::updateGlobalHistory): Changed code to use the new
+ -[WebHistory _addItemForURL:title:] method.
+
2008-03-05 Adam Roben <aroben@apple.com>
Rename WebCoreScriptDebuggerImp.{h,mm} to WebScriptDebugger.{h,mm}
/*
- * Copyright (C) 2005 Apple Computer, Inc. All rights reserved.
+ * Copyright (C) 2005, 2008 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#import "WebHistory.h"
-#import "WebHistoryPrivate.h"
+#import "WebHistoryInternal.h"
-#import "WebHistoryItem.h"
#import "WebHistoryItemInternal.h"
-#import "WebHistoryItemPrivate.h"
#import "WebKitLogging.h"
#import "WebNSURLExtras.h"
+#import <WebCore/KURL.h>
+#import <WebCore/Page.h>
+#import <WebCore/PageGroup.h>
#import <Foundation/NSError.h>
#import <JavaScriptCore/Assertions.h>
-#import <WebCore/WebCoreHistory.h>
-#import <wtf/Vector.h>
+#import <JavaScriptCore/HashMap.h>
+#import <JavaScriptCore/RetainPtr.h>
+#import <JavaScriptCore/Vector.h>
+
+using namespace WebCore;
+
+typedef int64_t WebHistoryDateKey;
+typedef HashMap<WebHistoryDateKey, RetainPtr<NSMutableArray> > DateToEntriesMap;
NSString *WebHistoryItemsAddedNotification = @"WebHistoryItemsAddedNotification";
NSString *WebHistoryItemsRemovedNotification = @"WebHistoryItemsRemovedNotification";
#define currentFileVersion 1
+@interface WebHistoryPrivate : NSObject {
+@private
+ NSMutableDictionary *_entriesByURL;
+ DateToEntriesMap* _entriesByDate;
+ NSMutableArray *_orderedLastVisitedDays;
+ BOOL itemLimitSet;
+ int itemLimit;
+ BOOL ageInDaysLimitSet;
+ int ageInDaysLimit;
+}
+
+- (void)addItem:(WebHistoryItem *)entry;
+- (void)addItems:(NSArray *)newEntries;
+- (BOOL)removeItem:(WebHistoryItem *)entry;
+- (BOOL)removeItems:(NSArray *)entries;
+- (BOOL)removeAllItems;
+- (void)setLastVisitedTimeInterval:(NSTimeInterval)time forItem:(WebHistoryItem *)item;
+
+- (NSArray *)orderedLastVisitedDays;
+- (NSArray *)orderedItemsLastVisitedOnDay:(NSCalendarDate *)calendarDate;
+- (BOOL)containsURL:(NSURL *)URL;
+- (BOOL)containsItemForURLString:(NSString *)URLString;
+- (WebHistoryItem *)itemForURL:(NSURL *)URL;
+- (WebHistoryItem *)itemForURLString:(NSString *)URLString;
+
+- (BOOL)loadFromURL:(NSURL *)URL collectDiscardedItemsInto:(NSMutableArray *)discardedItems error:(NSError **)error;
+- (BOOL)saveToURL:(NSURL *)URL error:(NSError **)error;
+
+- (NSCalendarDate *)ageLimitDate;
+
+- (void)setHistoryItemLimit:(int)limit;
+- (int)historyItemLimit;
+- (void)setHistoryAgeInDaysLimit:(int)limit;
+- (int)historyAgeInDaysLimit;
+
+- (void)addVisitedLinksToPageGroup:(PageGroup&)group;
+
+@end
+
@implementation WebHistoryPrivate
#pragma mark OBJECT FRAMEWORK
- (id)init
{
- if (![super init]) {
+ if (![super init])
return nil;
- }
_entriesByURL = [[NSMutableDictionary alloc] init];
_entriesByDate = new DateToEntriesMap;
[_entriesByURL release];
[_orderedLastVisitedDays release];
delete _entriesByDate;
-
[super dealloc];
}
[entriesForDate insertObject:entry atIndex:low];
}
-- (BOOL)_removeItemFromDateCaches:(WebHistoryItem *)entry
+- (BOOL)removeItemFromDateCaches:(WebHistoryItem *)entry
{
WebHistoryDateKey dateKey;
BOOL foundDate = [self findKey:&dateKey forDay:[entry lastVisitedTimeInterval]];
return YES;
}
-- (BOOL)removeItemForURLString: (NSString *)URLString
+- (BOOL)removeItemForURLString:(NSString *)URLString
{
- WebHistoryItem *entry = [_entriesByURL objectForKey: URLString];
- if (entry == nil) {
+ WebHistoryItem *entry = [_entriesByURL objectForKey:URLString];
+ if (!entry)
return NO;
- }
- [_entriesByURL removeObjectForKey: URLString];
+ [_entriesByURL removeObjectForKey:URLString];
#if ASSERT_DISABLED
- [self _removeItemFromDateCaches:entry];
+ [self removeItemFromDateCaches:entry];
#else
- BOOL itemWasInDateCaches = [self _removeItemFromDateCaches:entry];
+ BOOL itemWasInDateCaches = [self removeItemFromDateCaches:entry];
ASSERT(itemWasInDateCaches);
#endif
+ if (![_entriesByURL count])
+ PageGroup::removeAllVisitedLinks();
+
return YES;
}
-- (void)_addItemToDateCaches:(WebHistoryItem *)entry
+- (void)addItemToDateCaches:(WebHistoryItem *)entry
{
WebHistoryDateKey dateKey;
if ([self findKey:&dateKey forDay:[entry lastVisitedTimeInterval]])
[oldEntry release];
}
- [self _addItemToDateCaches:entry];
+ [self addItemToDateCaches:entry];
[_entriesByURL setObject:entry forKey:URLString];
}
#if ASSERT_DISABLED
[self _removeItemFromDateCaches:entry];
#else
- BOOL entryWasPresent = [self _removeItemFromDateCaches:entry];
+ BOOL entryWasPresent = [self removeItemFromDateCaches:entry];
ASSERT(entryWasPresent);
#endif
[entry _setLastVisitedTimeInterval:time];
- [self _addItemToDateCaches:entry];
+ [self addItemToDateCaches:entry];
// Don't send notification until entry is back in the right place in the date caches,
// since observers might fetch history by date when they receive the notification.
postNotificationName:WebHistoryItemChangedNotification object:entry userInfo:nil];
}
-- (BOOL)removeItem: (WebHistoryItem *)entry
+- (BOOL)removeItem:(WebHistoryItem *)entry
{
- WebHistoryItem *matchingEntry;
- NSString *URLString;
-
- URLString = [entry URLString];
+ NSString *URLString = [entry URLString];
// If this exact object isn't stored, then make no change.
// FIXME: Is this the right behavior if this entry isn't present, but another entry for the same URL is?
// Maybe need to change the API to make something like removeEntryForURLString public instead.
- matchingEntry = [_entriesByURL objectForKey: URLString];
- if (matchingEntry != entry) {
+ WebHistoryItem *matchingEntry = [_entriesByURL objectForKey:URLString];
+ if (matchingEntry != entry)
return NO;
- }
- [self removeItemForURLString: URLString];
+ [self removeItemForURLString:URLString];
return YES;
}
-- (BOOL)removeItems: (NSArray *)entries
+- (BOOL)removeItems:(NSArray *)entries
{
- int index, count;
-
- count = [entries count];
- if (count == 0) {
+ NSUInteger count = [entries count];
+ if (!count)
return NO;
- }
- for (index = 0; index < count; ++index) {
+ for (NSUInteger index = 0; index < count; ++index)
[self removeItem:[entries objectAtIndex:index]];
- }
return YES;
}
- (BOOL)removeAllItems
{
- if ([_entriesByURL count] == 0) {
+ if (_entriesByDate->isEmpty())
return NO;
- }
_entriesByDate->clear();
[_entriesByURL removeAllObjects];
[_orderedLastVisitedDays release];
_orderedLastVisitedDays = nil;
+ PageGroup::removeAllVisitedLinks();
+
return YES;
}
- (void)addItems:(NSArray *)newEntries
{
- NSEnumerator *enumerator;
- WebHistoryItem *entry;
-
// There is no guarantee that the incoming entries are in any particular
// order, but if this is called with a set of entries that were created by
// iterating through the results of orderedLastVisitedDays and orderedItemsLastVisitedOnDayy
// then they will be ordered chronologically from newest to oldest. We can make adding them
// faster (fewer compares) by inserting them from oldest to newest.
- enumerator = [newEntries reverseObjectEnumerator];
- while ((entry = [enumerator nextObject]) != nil) {
+ NSEnumerator *enumerator = [newEntries reverseObjectEnumerator];
+ while (WebHistoryItem *entry = [enumerator nextObject])
[self addItem:entry];
- }
}
#pragma mark DATE-BASED RETRIEVAL
return _orderedLastVisitedDays;
}
-- (NSArray *)orderedItemsLastVisitedOnDay: (NSCalendarDate *)date
+- (NSArray *)orderedItemsLastVisitedOnDay:(NSCalendarDate *)date
{
WebHistoryDateKey dateKey;
- if ([self findKey:&dateKey forDay:[date timeIntervalSinceReferenceDate]])
- return _entriesByDate->get(dateKey).get();
-
- return nil;
+ if (![self findKey:&dateKey forDay:[date timeIntervalSinceReferenceDate]])
+ return nil;
+ return _entriesByDate->get(dateKey).get();
}
#pragma mark URL MATCHING
- (WebHistoryItem *)itemForURLString:(NSString *)URLString
{
- return [_entriesByURL objectForKey: URLString];
+ return [_entriesByURL objectForKey:URLString];
}
-- (BOOL)containsItemForURLString: (NSString *)URLString
+- (BOOL)containsItemForURLString:(NSString *)URLString
{
return [self itemForURLString:URLString] != nil;
}
-- (BOOL)containsURL: (NSURL *)URL
+- (BOOL)containsURL:(NSURL *)URL
{
return [self itemForURLString:[URL _web_originalDataAsString]] != nil;
}
{
if (ageInDaysLimitSet)
return ageInDaysLimit;
- return [[NSUserDefaults standardUserDefaults] integerForKey: @"WebKitHistoryAgeInDaysLimit"];
+ return [[NSUserDefaults standardUserDefaults] integerForKey:@"WebKitHistoryAgeInDaysLimit"];
}
- (void)setHistoryItemLimit:(int)limit
{
if (itemLimitSet)
return itemLimit;
- return [[NSUserDefaults standardUserDefaults] integerForKey: @"WebKitHistoryItemLimit"];
+ return [[NSUserDefaults standardUserDefaults] integerForKey:@"WebKitHistoryItemLimit"];
}
// Return a date that marks the age limit for history entries saved to or
// loaded from disk. Any entry older than this item should be rejected.
-- (NSCalendarDate *)_ageLimitDate
+- (NSCalendarDate *)ageLimitDate
{
return [[NSCalendarDate calendarDate] dateByAddingYears:0 months:0 days:-[self historyAgeInDaysLimit]
hours:0 minutes:0 seconds:0];
return arrayRep;
}
-- (BOOL)_loadHistoryGutsFromURL:(NSURL *)URL savedItemsCount:(int *)numberOfItemsLoaded collectDiscardedItemsInto:(NSMutableArray *)discardedItems error:(NSError **)error
+- (BOOL)loadHistoryGutsFromURL:(NSURL *)URL savedItemsCount:(int *)numberOfItemsLoaded collectDiscardedItemsInto:(NSMutableArray *)discardedItems error:(NSError **)error
{
*numberOfItemsLoaded = 0;
NSDictionary *dictionary = nil;
NSNumber *fileVersionObject = [dictionary objectForKey:FileVersionKey];
int fileVersion;
// we don't trust data obtained from elsewhere, so double-check
- if (fileVersionObject != nil && [fileVersionObject isKindOfClass:[NSNumber class]]) {
- fileVersion = [fileVersionObject intValue];
- } else {
+ if (!fileVersionObject || ![fileVersionObject isKindOfClass:[NSNumber class]]) {
LOG_ERROR("history file version can't be determined, therefore not loading");
return NO;
}
+ fileVersion = [fileVersionObject intValue];
if (fileVersion > currentFileVersion) {
LOG_ERROR("history file version is %d, newer than newest known version %d, therefore not loading", fileVersion, currentFileVersion);
return NO;
NSArray *array = [dictionary objectForKey:DatesArrayKey];
int itemCountLimit = [self historyItemLimit];
- NSTimeInterval ageLimitDate = [[self _ageLimitDate] timeIntervalSinceReferenceDate];
+ NSTimeInterval ageLimitDate = [[self ageLimitDate] timeIntervalSinceReferenceDate];
NSEnumerator *enumerator = [array objectEnumerator];
BOOL ageLimitPassed = NO;
BOOL itemLimitPassed = NO;
- (BOOL)loadFromURL:(NSURL *)URL collectDiscardedItemsInto:(NSMutableArray *)discardedItems error:(NSError **)error
{
- int numberOfItems;
- double start, duration;
- BOOL result;
+ double start = CFAbsoluteTimeGetCurrent();
- start = CFAbsoluteTimeGetCurrent();
- result = [self _loadHistoryGutsFromURL:URL savedItemsCount:&numberOfItems collectDiscardedItemsInto:discardedItems error:error];
+ int numberOfItems;
+ if (![self loadHistoryGutsFromURL:URL savedItemsCount:&numberOfItems collectDiscardedItemsInto:discardedItems error:error])
+ return NO;
- if (result) {
- duration = CFAbsoluteTimeGetCurrent() - start;
- LOG(Timing, "loading %d history entries from %@ took %f seconds",
- numberOfItems, URL, duration);
- }
+ double duration = CFAbsoluteTimeGetCurrent() - start;
+ LOG(Timing, "loading %d history entries from %@ took %f seconds", numberOfItems, URL, duration);
- return result;
+ return YES;
}
-- (BOOL)_saveHistoryGuts: (int *)numberOfItemsSaved URL:(NSURL *)URL error:(NSError **)error
+- (BOOL)saveHistoryGuts:(int *)numberOfItemsSaved URL:(NSURL *)URL error:(NSError **)error
{
*numberOfItemsSaved = 0;
- // FIXME: Correctly report error when new API is ready.
- if (error)
- *error = nil;
-
NSArray *array = [self arrayRepresentation];
NSDictionary *dictionary = [NSDictionary dictionaryWithObjectsAndKeys:
array, DatesArrayKey,
[NSNumber numberWithInt:currentFileVersion], FileVersionKey,
nil];
NSData *data = [NSPropertyListSerialization dataFromPropertyList:dictionary format:NSPropertyListBinaryFormat_v1_0 errorDescription:nil];
- if (![data writeToURL:URL atomically:YES]) {
+ if (![data writeToURL:URL options:0 error:error]) {
LOG_ERROR("attempt to save %@ to %@ failed", dictionary, URL);
return NO;
}
-
+
*numberOfItemsSaved = [array count];
return YES;
}
- (BOOL)saveToURL:(NSURL *)URL error:(NSError **)error
{
- int numberOfItems;
- double start, duration;
- BOOL result;
-
- start = CFAbsoluteTimeGetCurrent();
- result = [self _saveHistoryGuts: &numberOfItems URL:URL error:error];
-
- if (result) {
- duration = CFAbsoluteTimeGetCurrent() - start;
- LOG(Timing, "saving %d history entries to %@ took %f seconds",
- numberOfItems, URL, duration);
- }
-
- return result;
-}
-
-@end
-
-@interface _WebCoreHistoryProvider : NSObject <WebCoreHistoryProvider>
-{
- WebHistory *history;
-}
-- initWithHistory: (WebHistory *)h;
-@end
+ double start = CFAbsoluteTimeGetCurrent();
-@implementation _WebCoreHistoryProvider
-- initWithHistory: (WebHistory *)h
-{
- history = [h retain];
- return self;
-}
+ int numberOfItems;
+ if (![self saveHistoryGuts:&numberOfItems URL:URL error:error])
+ return NO;
-static inline bool matchLetter(char c, char lowercaseLetter)
-{
- return (c | 0x20) == lowercaseLetter;
-}
+ double duration = CFAbsoluteTimeGetCurrent() - start;
+ LOG(Timing, "saving %d history entries to %@ took %f seconds", numberOfItems, URL, duration);
-static inline bool matchUnicodeLetter(UniChar c, UniChar lowercaseLetter)
-{
- return (c | 0x20) == lowercaseLetter;
+ return YES;
}
-#define UNICODE_BUFFER_SIZE 1024
-
-- (BOOL)containsURL:(const UniChar *)unicode length:(unsigned)length
+- (void)addVisitedLinksToPageGroup:(PageGroup&)group
{
- const UniChar *unicodeStr = unicode;
- UniChar staticStrBuffer[UNICODE_BUFFER_SIZE];
- UniChar *strBuffer = NULL;
- BOOL needToAddSlash = FALSE;
-
- if (length >= 6 &&
- matchUnicodeLetter(unicode[0], 'h') &&
- matchUnicodeLetter(unicode[1], 't') &&
- matchUnicodeLetter(unicode[2], 't') &&
- matchUnicodeLetter(unicode[3], 'p') &&
- (unicode[4] == ':'
- || (matchUnicodeLetter(unicode[4], 's') && unicode[5] == ':'))) {
-
- unsigned pos = unicode[4] == ':' ? 5 : 6;
-
- // skip possible initial two slashes
- if (pos + 1 < length && unicode[pos] == '/' && unicode[pos + 1] == '/') {
- pos += 2;
+ NSEnumerator *enumerator = [_entriesByURL keyEnumerator];
+ while (NSString *url = [enumerator nextObject]) {
+ size_t length = [url length];
+ const UChar* characters = CFStringGetCharactersPtr(reinterpret_cast<CFStringRef>(url));
+ if (characters)
+ group.addVisitedLink(characters, length);
+ else {
+ Vector<UChar, 512> buffer(length);
+ [url getCharacters:buffer.data()];
+ group.addVisitedLink(buffer.data(), length);
}
-
- while (pos < length && unicode[pos] != '/') {
- pos++;
- }
-
- if (pos == length) {
- needToAddSlash = TRUE;
- }
- }
-
- if (needToAddSlash) {
- if (length + 1 <= UNICODE_BUFFER_SIZE) {
- strBuffer = staticStrBuffer;
- } else {
- strBuffer = (UniChar*)malloc(sizeof(UniChar) * (length + 1));
- }
- memcpy(strBuffer, unicode, 2 * length);
- strBuffer[length] = '/';
- length++;
-
- unicodeStr = strBuffer;
- }
-
- CFStringRef str = CFStringCreateWithCharactersNoCopy(NULL, unicodeStr, length, kCFAllocatorNull);
- BOOL result = [history containsItemForURLString:(id)str];
- CFRelease(str);
-
- if (strBuffer != staticStrBuffer) {
- free(strBuffer);
}
-
- return result;
-}
-
-- (void)dealloc
-{
- [history release];
- [super dealloc];
}
@end
return _sharedHistory;
}
-
-+ (void)setOptionalSharedHistory: (WebHistory *)history
++ (void)setOptionalSharedHistory:(WebHistory *)history
{
- // FIXME. Need to think about multiple instances of WebHistory per application
+ // FIXME: Need to think about multiple instances of WebHistory per application
// and correct synchronization of history file between applications.
- [WebCoreHistory setHistoryProvider: [[[_WebCoreHistoryProvider alloc] initWithHistory: history] autorelease]];
- if (_sharedHistory != history){
+ if (_sharedHistory != history) {
[_sharedHistory release];
_sharedHistory = [history retain];
}
- (id)init
{
- if ((self = [super init]) != nil) {
- _historyPrivate = [[WebHistoryPrivate alloc] init];
- }
-
+ self = [super init];
+ if (!self)
+ return nil;
+ _historyPrivate = [[WebHistoryPrivate alloc] init];
return self;
}
{
NSDictionary *userInfo = [NSDictionary dictionaryWithObjectsAndKeys:entries, WebHistoryItemsKey, nil];
[[NSNotificationCenter defaultCenter]
- postNotificationName: name object: self userInfo: userInfo];
+ postNotificationName:name object:self userInfo:userInfo];
}
-- (WebHistoryItem *)addItemForURL: (NSURL *)URL
-{
- WebHistoryItem *entry = [[WebHistoryItem alloc] initWithURL:URL title:nil];
- [entry _setLastVisitedTimeInterval: [NSDate timeIntervalSinceReferenceDate]];
- [self addItem: entry];
- [entry release];
- return entry;
-}
-
-
-- (void)addItem: (WebHistoryItem *)entry
-{
- LOG (History, "adding %@", entry);
- [_historyPrivate addItem: entry];
- [self _sendNotification: WebHistoryItemsAddedNotification
- entries: [NSArray arrayWithObject:entry]];
-}
-
-- (void)removeItem: (WebHistoryItem *)entry
-{
- if ([_historyPrivate removeItem: entry]) {
- [self _sendNotification: WebHistoryItemsRemovedNotification
- entries: [NSArray arrayWithObject:entry]];
- }
-}
-
-- (void)removeItems: (NSArray *)entries
+- (void)removeItems:(NSArray *)entries
{
if ([_historyPrivate removeItems:entries]) {
- [self _sendNotification: WebHistoryItemsRemovedNotification
- entries: entries];
+ [self _sendNotification:WebHistoryItemsRemovedNotification
+ entries:entries];
}
}
{
if ([_historyPrivate removeAllItems]) {
[[NSNotificationCenter defaultCenter]
- postNotificationName: WebHistoryAllItemsRemovedNotification
- object: self];
+ postNotificationName:WebHistoryAllItemsRemovedNotification
+ object:self];
}
}
- (void)addItems:(NSArray *)newEntries
{
[_historyPrivate addItems:newEntries];
- [self _sendNotification: WebHistoryItemsAddedNotification
- entries: newEntries];
-}
-
-- (void)setLastVisitedTimeInterval:(NSTimeInterval)time forItem:(WebHistoryItem *)entry
-{
- [_historyPrivate setLastVisitedTimeInterval:time forItem:entry];
+ [self _sendNotification:WebHistoryItemsAddedNotification
+ entries:newEntries];
}
#pragma mark DATE-BASED RETRIEVAL
return [_historyPrivate orderedLastVisitedDays];
}
-- (NSArray *)orderedItemsLastVisitedOnDay: (NSCalendarDate *)date
+- (NSArray *)orderedItemsLastVisitedOnDay:(NSCalendarDate *)date
{
- return [_historyPrivate orderedItemsLastVisitedOnDay: date];
+ return [_historyPrivate orderedItemsLastVisitedOnDay:date];
}
#pragma mark URL MATCHING
-- (BOOL)containsItemForURLString: (NSString *)URLString
-{
- return [_historyPrivate containsItemForURLString: URLString];
-}
-
-- (BOOL)containsURL: (NSURL *)URL
+- (BOOL)containsURL:(NSURL *)URL
{
- return [_historyPrivate containsURL: URL];
+ return [_historyPrivate containsURL:URL];
}
- (WebHistoryItem *)itemForURL:(NSURL *)URL
- (BOOL)loadFromURL:(NSURL *)URL error:(NSError **)error
{
- NSMutableArray *discardedItems = [NSMutableArray array];
-
- if ([_historyPrivate loadFromURL:URL collectDiscardedItemsInto:discardedItems error:error]) {
- [[NSNotificationCenter defaultCenter]
- postNotificationName:WebHistoryLoadedNotification
- object:self];
-
- if ([discardedItems count] > 0)
- [self _sendNotification:WebHistoryItemsDiscardedWhileLoadingNotification entries:discardedItems];
-
- return YES;
+ NSMutableArray *discardedItems = [[NSMutableArray alloc] init];
+ if (![_historyPrivate loadFromURL:URL collectDiscardedItemsInto:discardedItems error:error]) {
+ [discardedItems release];
+ return NO;
}
- return NO;
-}
-- (BOOL)saveToURL:(NSURL *)URL error:(NSError **)error
-{
- // FIXME: Use new foundation API to get error when ready.
- if([_historyPrivate saveToURL:URL error:error]){
- [[NSNotificationCenter defaultCenter]
- postNotificationName: WebHistorySavedNotification
- object: self];
- return YES;
- }
- return NO;
-}
+ [[NSNotificationCenter defaultCenter]
+ postNotificationName:WebHistoryLoadedNotification
+ object:self];
-- (WebHistoryItem *)_itemForURLString:(NSString *)URLString
-{
- return [_historyPrivate itemForURLString: URLString];
+ if ([discardedItems count])
+ [self _sendNotification:WebHistoryItemsDiscardedWhileLoadingNotification entries:discardedItems];
+
+ [discardedItems release];
+ return YES;
}
-- (NSCalendarDate*)ageLimitDate
+- (BOOL)saveToURL:(NSURL *)URL error:(NSError **)error
{
- return [_historyPrivate _ageLimitDate];
+ if (![_historyPrivate saveToURL:URL error:error])
+ return NO;
+ [[NSNotificationCenter defaultCenter]
+ postNotificationName:WebHistorySavedNotification
+ object:self];
+ return YES;
}
- (void)setHistoryItemLimit:(int)limit
}
@end
+
+@implementation WebHistory (WebPrivate)
+
+- (void)addItem:(WebHistoryItem *)entry
+{
+ LOG(History, "adding %@", entry);
+ [_historyPrivate addItem:entry];
+ [self _sendNotification:WebHistoryItemsAddedNotification
+ entries:[NSArray arrayWithObject:entry]];
+}
+
+- (WebHistoryItem *)addItemForURL:(NSURL *)URL
+{
+ WebHistoryItem *entry = [[WebHistoryItem alloc] initWithURL:URL title:nil];
+ [entry _setLastVisitedTimeInterval:[NSDate timeIntervalSinceReferenceDate]];
+ [self addItem:entry];
+ [entry release];
+ return entry;
+}
+
+- (NSCalendarDate *)ageLimitDate
+{
+ return [_historyPrivate ageLimitDate];
+}
+
+- (BOOL)containsItemForURLString:(NSString *)URLString
+{
+ return [_historyPrivate containsItemForURLString:URLString];
+}
+
+- (void)removeItem:(WebHistoryItem *)entry
+{
+ if ([_historyPrivate removeItem:entry]) {
+ [self _sendNotification:WebHistoryItemsRemovedNotification
+ entries:[NSArray arrayWithObject:entry]];
+ }
+}
+
+- (void)setLastVisitedTimeInterval:(NSTimeInterval)time forItem:(WebHistoryItem *)entry
+{
+ [_historyPrivate setLastVisitedTimeInterval:time forItem:entry];
+}
+
+- (WebHistoryItem *)_itemForURLString:(NSString *)URLString
+{
+ return [_historyPrivate itemForURLString:URLString];
+}
+
+@end
+
+@implementation WebHistory (WebInternal)
+
+- (void)_addItemForURL:(NSURL *)URL title:(NSString *)title
+{
+ WebHistoryItem *entry = [[WebHistoryItem alloc] initWithURL:URL title:title];
+ [entry _setLastVisitedTimeInterval:[NSDate timeIntervalSinceReferenceDate]];
+ [self addItem:entry];
+ [entry release];
+}
+
+- (void)_addVisitedLinksToPageGroup:(WebCore::PageGroup&)group
+{
+ [_historyPrivate addVisitedLinksToPageGroup:group];
+}
+
+@end
--- /dev/null
+/*
+ * Copyright (C) 2008 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#import "WebHistoryPrivate.h"
+
+namespace WebCore {
+ class PageGroup;
+}
+
+@interface WebHistory (WebInternal)
+- (void)_addItemForURL:(NSURL *)URL title:(NSString *)title;
+- (void)_addVisitedLinksToPageGroup:(WebCore::PageGroup&)group;
+@end
/*
- * Copyright (C) 2006 Apple Computer, Inc. All rights reserved.
+ * Copyright (C) 2006, 2008 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#import <Cocoa/Cocoa.h>
+#import "WebHistoryItemPrivate.h"
-#import <WebKit/WebBackForwardList.h>
-#import <WebKit/WebHistoryItem.h>
-#import <wtf/PassRefPtr.h>
+#import <JavaScriptCore/PassRefPtr.h>
namespace WebCore {
class HistoryItem;
@end
-@interface WebBackForwardList (WebPrivate)
+@interface WebBackForwardList (WebInternal)
- (void)_close;
@end
-
-
/*
- * Copyright (C) 2005 Apple Computer, Inc. All rights reserved.
+ * Copyright (C) 2005, 2008 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#import <Foundation/Foundation.h>
-
#import <WebKit/WebHistory.h>
-@class WebHistoryItem;
-@class NSError;
-
-#ifdef __cplusplus
-#include <wtf/HashMap.h>
-#include <wtf/RetainPtr.h>
-
-typedef int64_t WebHistoryDateKey;
-typedef HashMap<WebHistoryDateKey, RetainPtr<NSMutableArray> > DateToEntriesMap;
-#else
-typedef struct DateToEntriesMap DateToEntriesMap;
-#endif
-
/*
@constant WebHistoryItemsDiscardedWhileLoadingNotification Posted from loadFromURL:error:.
This notification comes with a userInfo dictionary that contains the array of
- items discarded due to the date limit or item limit. The key for the array is WebHistoryItemsKey.
+ items discarded due to the date limit or item limit. The key for the array is WebHistoryItemsKey.
*/
-// FIXME: This notification should become API in WebHistory.h
+// FIXME: This notification should become public API.
extern NSString *WebHistoryItemsDiscardedWhileLoadingNotification;
-// FIXME: The WebHistoryPrivate interface should be in WebHistoryInternal.h or inside WebHistory.m
-@interface WebHistoryPrivate : NSObject {
-@private
- NSMutableDictionary *_entriesByURL;
- DateToEntriesMap* _entriesByDate;
- NSMutableArray *_orderedLastVisitedDays;
- BOOL itemLimitSet;
- int itemLimit;
- BOOL ageInDaysLimitSet;
- int ageInDaysLimit;
-}
-
-- (void)addItem:(WebHistoryItem *)entry;
-- (void)addItems:(NSArray *)newEntries;
-- (BOOL)removeItem:(WebHistoryItem *)entry;
-- (BOOL)removeItems:(NSArray *)entries;
-- (BOOL)removeAllItems;
-- (void)setLastVisitedTimeInterval:(NSTimeInterval)time forItem:(WebHistoryItem *)item;
-
-- (NSArray *)orderedLastVisitedDays;
-- (NSArray *)orderedItemsLastVisitedOnDay:(NSCalendarDate *)calendarDate;
-- (BOOL)containsItemForURLString:(NSString *)URLString;
-- (BOOL)containsURL:(NSURL *)URL;
-- (WebHistoryItem *)itemForURL:(NSURL *)URL;
-- (WebHistoryItem *)itemForURLString:(NSString *)URLString;
-
-- (BOOL)loadFromURL:(NSURL *)URL collectDiscardedItemsInto:(NSMutableArray *)discardedItems error:(NSError **)error;
-- (BOOL)saveToURL:(NSURL *)URL error:(NSError **)error;
-
-- (NSCalendarDate*)_ageLimitDate;
-
-- (void)setHistoryItemLimit:(int)limit;
-- (int)historyItemLimit;
-- (void)setHistoryAgeInDaysLimit:(int)limit;
-- (int)historyAgeInDaysLimit;
-
-@end
-
@interface WebHistory (WebPrivate)
// FIXME: The following SPI is used by Safari. Should it be made into public API?
- (WebHistoryItem *)_itemForURLString:(NSString *)URLString;
-// FIXME: Safari doesn't use the following SPI, and it's used in WebKit only inside WebHistory.m.
-// Should we move it into a FileInternal category inside WebHistory.m, or do we need it for other
-// clients?
-- (void)removeItem:(WebHistoryItem *)entry;
+// FIXME: neither Safari nor WebKit use the following SPI -- do we still need them?
- (void)addItem:(WebHistoryItem *)entry;
-- (BOOL)containsItemForURLString:(NSString *)URLString;
-
-// FIXME: Safari doesn't use the following SPI, but other WebKit classes do. Should we move it into
-// a WebHistoryInternal.h, or do we need it for other clients?
- (WebHistoryItem *)addItemForURL:(NSURL *)URL;
-// Change date on existing item
+- (NSCalendarDate *)ageLimitDate;
+- (BOOL)containsItemForURLString:(NSString *)URLString;
+- (void)removeItem:(WebHistoryItem *)entry;
- (void)setLastVisitedTimeInterval:(NSTimeInterval)time forItem:(WebHistoryItem *)item;
-// FIXME: neither Safari nor WebKit use the following SPI -- do we still need it?
-- (NSCalendarDate*)ageLimitDate;
-
@end
virtual void exceededDatabaseQuota(WebCore::Frame*, const WebCore::String& databaseName);
+ virtual void populateVisitedLinks();
+
virtual void dashboardRegionsChanged();
private:
#import "WebFrameView.h"
#import "WebHTMLView.h"
#import "WebHTMLViewPrivate.h"
+#import "WebHistoryInternal.h"
#import "WebKitSystemInterface.h"
#import "WebNSURLRequestExtras.h"
-#import "WebSecurityOriginPrivate.h"
#import "WebSecurityOriginInternal.h"
#import "WebUIDelegate.h"
#import "WebUIDelegatePrivate.h"
#import <WebCore/FrameLoadRequest.h>
#import <WebCore/HitTestResult.h>
#import <WebCore/IntRect.h>
+#import <WebCore/Page.h>
#import <WebCore/PlatformScreen.h>
#import <WebCore/PlatformString.h>
#import <WebCore/ResourceRequest.h>
CallUIDelegate(m_webView, @selector(webView:frame:exceededDatabaseQuotaForSecurityOrigin:database:), kit(frame), webOrigin, (NSString *)databaseName);
[webOrigin release];
}
+
+void WebChromeClient::populateVisitedLinks()
+{
+ [[WebHistory optionalSharedHistory] _addVisitedLinksToPageGroup:[m_webView page]->group()];
+}
void WebChromeClient::dashboardRegionsChanged()
{
#import "WebHTMLRepresentationPrivate.h"
#import "WebHTMLViewInternal.h"
#import "WebHistoryItemInternal.h"
-#import "WebHistoryItemPrivate.h"
-#import "WebHistoryPrivate.h"
+#import "WebHistoryInternal.h"
#import "WebIconDatabaseInternal.h"
#import "WebKitErrorsPrivate.h"
#import "WebKitLogging.h"
void WebFrameLoaderClient::updateGlobalHistory(const KURL& url)
{
NSURL *cocoaURL = url;
- WebHistoryItem *entry = [[WebHistory optionalSharedHistory] addItemForURL:cocoaURL];
const String& pageTitle = core(m_webFrame.get())->loader()->documentLoader()->title();
- if (!pageTitle.isEmpty())
- [entry setTitle:pageTitle];
+ [[WebHistory optionalSharedHistory] _addItemForURL:cocoaURL title:pageTitle];
}
bool WebFrameLoaderClient::shouldGoToHistoryItem(HistoryItem* item) const
+2008-03-06 Darin Adler <darin@apple.com>
+
+ Reviewed by Mitz.
+
+ - fix http://bugs.webkit.org/show_bug.cgi?id=17526
+ REGRESSION: iframes are added to Safari's History menu
+ by separating the visited link machinery from global history
+
+ * WebCoreSupport/WebChromeClient.cpp:
+ (WebChromeClient::populateVisitedLinks): Added a call to the new
+ WebHistory::addVisitedLinksToPageGroup function.
+ * WebCoreSupport/WebChromeClient.h: Added populateVisitedLinks.
+ Also fixed the webView function to be non-virtual.
+
+ * WebCoreSupport/WebFrameLoaderClient.cpp:
+ (WebFrameLoaderClient::updateGlobalHistory): Changed to use the
+ new WebHistory::addItem function.
+ (WebFrameLoaderClient::webHistory): Changed to return a WebHistory*,
+ there's no reason to AddRef the result from this function.
+ * WebCoreSupport/WebFrameLoaderClient.h: Ditto.
+
+ * WebHistory.cpp: Removed IWebHistoryPrivate and _WebCoreHistoryProvider.
+ (WebHistory::QueryInterface): Removed IWebHistoryPrivate.
+ (sharedHistoryStorage): Added.
+ (WebHistory::sharedHistory): Added.
+ (WebHistory::optionalSharedHistory): Changed to use sharedHistory().
+ (WebHistory::setOptionalSharedHistory): Changed to require a WebHistory
+ object, not just an IWebHistory.
+ (WebHistory::removeAllItems): Call PageGroup::removeAllVisitedLinks.
+ (WebHistory::addItem): Changed parameter types since this is called with
+ arguments from WebCore -- at some point this could allow better efficiency.
+ (WebHistory::removeItemForURLString): Call PageGroup::removeAllVisitedLinks
+ if the last URL is being removed.
+ (addVisitedLinkToPageGroup): Added. Helper. Adds a single link to a group's
+ visited link set.
+ (WebHistory::addVisitedLinksToPageGroup): Added. Adds all links to a group's
+ visited link.
+ * WebHistory.h: Removed IWebHistoryPrivate. Removed optionalSharedHistoryInternal
+ and added sharedHistory. Replaced addItemForURL and containsItemForURLString with
+ non-virtual addItem and addVisitedLinksToPageGroup functions.
+
2008-03-05 Anders Carlsson <andersca@apple.com>
Build fix.
/*
- * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
+ * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
#include "WebElementPropertyBag.h"
#include "WebFrame.h"
+#include "WebHistory.h"
#include "WebMutableURLRequest.h"
#include "WebSecurityOrigin.h"
#include "WebView.h"
#include <WebCore/FloatRect.h>
#include <WebCore/FrameLoadRequest.h>
#include <WebCore/FrameView.h>
+#include <WebCore/Page.h>
#include <WebCore/WindowFeatures.h>
#pragma warning(pop)
}
}
+void WebChromeClient::populateVisitedLinks()
+{
+ WebHistory::sharedHistory()->addVisitedLinksToPageGroup(m_webView->page()->group());
+}
+
COMPtr<IWebUIDelegate> WebChromeClient::uiDelegate()
{
COMPtr<IWebUIDelegate> delegate;
virtual void exceededDatabaseQuota(WebCore::Frame*, const WebCore::String&);
- virtual WebView* webView() const { return m_webView; }
+ virtual void populateVisitedLinks();
+
+ WebView* webView() const { return m_webView; }
private:
COMPtr<IWebUIDelegate> uiDelegate();
#include <WebCore/PluginPackage.h>
#include <WebCore/PluginView.h>
#include <WebCore/RenderPart.h>
+#include <WebCore/ResourceHandle.h>
#pragma warning(pop)
using namespace WebCore;
void WebFrameLoaderClient::updateGlobalHistory(const KURL& url)
{
- COMPtr<WebHistory> history = webHistory();
- if (!history)
- return;
- history->addItemForURL(BString(url.string()), 0);
+ WebHistory::sharedHistory()->addItem(url, core(m_webFrame)->loader()->documentLoader()->title());
}
bool WebFrameLoaderClient::shouldGoToHistoryItem(HistoryItem*) const
m_pluginView = static_cast<PluginView*>(pluginWidget);
}
-COMPtr<WebHistory> WebFrameLoaderClient::webHistory() const
+WebHistory* WebFrameLoaderClient::webHistory() const
{
if (m_webFrame != m_webFrame->webView()->topLevelFrame())
return 0;
- IWebHistoryPrivate* historyInternal = WebHistory::optionalSharedHistoryInternal(); // does not add a ref
- if (!historyInternal)
- return 0;
-
- return COMPtr<WebHistory>(Query, historyInternal);
+ return WebHistory::sharedHistory();
}
PassRefPtr<WebCore::Frame> createFrame(const WebCore::KURL&, const WebCore::String& name, WebCore::HTMLFrameOwnerElement*, const WebCore::String& referrer);
void loadURLIntoChild(const WebCore::KURL&, const WebCore::String& referrer, WebFrame* childFrame);
void receivedData(const char*, int, const WebCore::String&);
- COMPtr<WebHistory> webHistory() const;
+ WebHistory* webHistory() const;
WebFrame* m_webFrame;
#include "WebNotificationCenter.h"
#include "WebPreferences.h"
#include <CoreFoundation/CoreFoundation.h>
-#include <WebCore/WebCoreHistory.h>
#pragma warning( push, 0 )
#include <wtf/Vector.h>
+#include <WebCore/KURL.h>
+#include <WebCore/PageGroup.h>
#pragma warning( pop )
+using namespace WebCore;
+
CFStringRef DatesArrayKey = CFSTR("WebHistoryDates");
CFStringRef FileVersionKey = CFSTR("WebHistoryFileVersion");
-const IID IID_IWebHistoryPrivate = { 0x3de04e59, 0x93f9, 0x4369, { 0x8b, 0x43, 0x97, 0x64, 0x58, 0xd7, 0xe3, 0x19 } };
-
#define currentFileVersion 1
-class _WebCoreHistoryProvider : public WebCore::WebCoreHistoryProvider {
-public:
- _WebCoreHistoryProvider(IWebHistory* history);
- ~_WebCoreHistoryProvider();
-
- virtual bool containsURL(const UChar* unicode, unsigned length);
-
-private:
- IWebHistory* m_history;
- IWebHistoryPrivate* m_historyPrivate;
-};
-
static bool areEqualOrClose(double d1, double d2)
{
double diff = d1-d2;
// WebHistory -----------------------------------------------------------------
-IWebHistory* WebHistory::m_optionalSharedHistory = 0;
-
WebHistory::WebHistory()
: m_refCount(0)
, m_preferences(0)
*ppvObject = static_cast<IWebHistory*>(this);
else if (IsEqualGUID(riid, IID_IWebHistory))
*ppvObject = static_cast<IWebHistory*>(this);
- else if (IsEqualGUID(riid, IID_IWebHistoryPrivate))
- *ppvObject = static_cast<IWebHistoryPrivate*>(this);
else
return E_NOINTERFACE;
// IWebHistory ----------------------------------------------------------------
+static inline COMPtr<WebHistory>& sharedHistoryStorage()
+{
+ static COMPtr<WebHistory> sharedHistory;
+ return sharedHistory;
+}
+
+WebHistory* WebHistory::sharedHistory()
+{
+ return sharedHistoryStorage().get();
+}
+
HRESULT STDMETHODCALLTYPE WebHistory::optionalSharedHistory(
/* [retval][out] */ IWebHistory** history)
{
- *history = m_optionalSharedHistory;
- if (m_optionalSharedHistory)
- m_optionalSharedHistory->AddRef();
-
+ *history = sharedHistory();
+ if (*history)
+ (*history)->AddRef();
return S_OK;
}
HRESULT STDMETHODCALLTYPE WebHistory::setOptionalSharedHistory(
/* [in] */ IWebHistory* history)
{
- if (m_optionalSharedHistory) {
- m_optionalSharedHistory->Release();
- m_optionalSharedHistory = 0;
- }
-
- _WebCoreHistoryProvider* coreHistory = 0;
- m_optionalSharedHistory = history;
- if (history) {
- history->AddRef();
- coreHistory = new _WebCoreHistoryProvider(history);
- }
- WebCore::WebCoreHistory::setHistoryProvider(coreHistory);
-
+ sharedHistoryStorage().query(history);
return S_OK;
}
CFArrayRemoveAllValues(m_datesWithEntries.get());
CFDictionaryRemoveAllValues(m_entriesByURL.get());
+ PageGroup::removeAllVisitedLinks();
+
return postNotification(kWebHistoryAllItemsRemovedNotification);
}
return hr;
}
-HRESULT WebHistory::addItemForURL(BSTR url, BSTR title)
+void WebHistory::addItem(const KURL& url, const String& title)
{
COMPtr<WebHistoryItem> item(AdoptCOM, WebHistoryItem::createInstance());
if (!item)
- return E_FAIL;
+ return;
SYSTEMTIME currentTime;
GetSystemTime(¤tTime);
DATE lastVisited;
if (!SystemTimeToVariantTime(¤tTime, &lastVisited))
- return E_FAIL;
+ return;
- HRESULT hr = item->initWithURLString(url, title, 0);
+ HRESULT hr = item->initWithURLString(BString(url.string()), BString(title), 0);
if (FAILED(hr))
- return hr;
+ return;
hr = item->setLastVisitedTimeInterval(lastVisited); // also increments visitedCount
if (FAILED(hr))
- return hr;
+ return;
- return addItem(item.get());
+ addItem(item.get());
}
HRESULT WebHistory::itemForURLString(
return itemForURLString(urlString.get(), item);
}
-HRESULT WebHistory::containsItemForURLString(
- /* [in] */ void* urlCFString,
- /* [retval][out] */ BOOL* contains)
-{
- IWebHistoryItem* item = 0;
- HRESULT hr;
- if (SUCCEEDED(hr = itemForURLString((CFStringRef)urlCFString, &item))) {
- *contains = TRUE;
- // itemForURLString refs the returned item, so we need to balance that
- item->Release();
- } else
- *contains = FALSE;
-
- return hr;
-}
-
HRESULT WebHistory::removeItemForURLString(CFStringRef urlString)
{
IWebHistoryItem* entry = (IWebHistoryItem*) CFDictionaryGetValue(m_entriesByURL.get(), urlString);
HRESULT hr = removeItemFromDateCaches(entry);
CFDictionaryRemoveValue(m_entriesByURL.get(), urlString);
+ if (!CFDictionaryGetCount(m_entriesByURL.get()))
+ PageGroup::removeAllVisitedLinks();
+
return hr;
}
return S_OK;
}
-IWebHistoryPrivate* WebHistory::optionalSharedHistoryInternal()
-{
- if (!m_optionalSharedHistory)
- return 0;
-
- IWebHistoryPrivate* historyPrivate;
- if (FAILED(m_optionalSharedHistory->QueryInterface(IID_IWebHistoryPrivate, (void**)&historyPrivate)))
- return 0;
-
- historyPrivate->Release(); // don't add an additional ref for this internal call
- return historyPrivate;
-}
-
-// _WebCoreHistoryProvider ----------------------------------------------------------------
-
-_WebCoreHistoryProvider::_WebCoreHistoryProvider(IWebHistory* history)
- : m_history(history)
- , m_historyPrivate(0)
-{
-}
-
-_WebCoreHistoryProvider::~_WebCoreHistoryProvider()
-{
-}
-
-static inline bool matchLetter(char c, char lowercaseLetter)
+static void addVisitedLinkToPageGroup(const void* key, const void*, void* context)
{
- return (c | 0x20) == lowercaseLetter;
-}
+ CFStringRef url = static_cast<CFStringRef>(key);
+ PageGroup* group = static_cast<PageGroup*>(context);
-static inline bool matchUnicodeLetter(UniChar c, UniChar lowercaseLetter)
-{
- return (c | 0x20) == lowercaseLetter;
+ CFIndex length = CFStringGetLength(url);
+ const UChar* characters = reinterpret_cast<const UChar*>(CFStringGetCharactersPtr(url));
+ if (characters)
+ group->addVisitedLink(characters, length);
+ else {
+ Vector<UChar, 512> buffer(length);
+ CFStringGetCharacters(url, CFRangeMake(0, length), reinterpret_cast<UniChar*>(buffer.data()));
+ group->addVisitedLink(buffer.data(), length);
+ }
}
-bool _WebCoreHistoryProvider::containsURL(const UChar* unicode, unsigned length)
+void WebHistory::addVisitedLinksToPageGroup(PageGroup& group)
{
- const int bufferSize = 1024;
- const UChar *unicodeStr = unicode;
- UChar staticStrBuffer[bufferSize];
- UChar *strBuffer = 0;
- bool needToAddSlash = false;
-
- if (length >= 6 &&
- matchUnicodeLetter(unicode[0], 'h') &&
- matchUnicodeLetter(unicode[1], 't') &&
- matchUnicodeLetter(unicode[2], 't') &&
- matchUnicodeLetter(unicode[3], 'p') &&
- (unicode[4] == ':'
- || (matchUnicodeLetter(unicode[4], 's') && unicode[5] == ':'))) {
-
- unsigned pos = unicode[4] == ':' ? 5 : 6;
-
- // skip possible initial two slashes
- if (pos + 1 < length && unicode[pos] == '/' && unicode[pos + 1] == '/')
- pos += 2;
-
- while (pos < length && unicode[pos] != '/')
- pos++;
-
- if (pos == length)
- needToAddSlash = true;
- }
-
- if (needToAddSlash) {
- if (length + 1 <= bufferSize)
- strBuffer = staticStrBuffer;
- else
- strBuffer = (UChar*)malloc(sizeof(UChar) * (length + 1));
- memcpy(strBuffer, unicode, 2 * length);
- strBuffer[length] = '/';
- length++;
-
- unicodeStr = strBuffer;
- }
-
- if (!m_historyPrivate) {
- if (SUCCEEDED(m_history->QueryInterface(IID_IWebHistoryPrivate, (void**)&m_historyPrivate))) {
- // don't hold a ref - we're owned by IWebHistory/IWebHistoryPrivate
- m_historyPrivate->Release();
- } else {
- if (strBuffer != staticStrBuffer)
- free(strBuffer);
- m_historyPrivate = 0;
- return false;
- }
- }
-
- CFStringRef str = CFStringCreateWithCharactersNoCopy(NULL, (const UniChar*)unicodeStr, length, kCFAllocatorNull);
- BOOL result = FALSE;
- m_historyPrivate->containsItemForURLString((void*)str, &result);
- CFRelease(str);
-
- if (strBuffer != staticStrBuffer)
- free(strBuffer);
-
- return !!result;
+ CFDictionaryApplyFunction(m_entriesByURL.get(), addVisitedLinkToPageGroup, &group);
}
/*
- * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
+ * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
#include <CoreFoundation/CoreFoundation.h>
#include <wtf/RetainPtr.h>
-//-----------------------------------------------------------------------------
-
-// {3DE04E59-93F9-4369-8B43-976458D7E319}
-DEFINE_GUID(IID_IWebHistoryPrivate, 0x3de04e59, 0x93f9, 0x4369, 0x8b, 0x43, 0x97, 0x64, 0x58, 0xd7, 0xe3, 0x19);
-
-interface IWebHistoryPrivate : public IUnknown
-{
-public:
- virtual HRESULT STDMETHODCALLTYPE addItemForURL(
- /* [in] */ BSTR url,
- /* [in] */ BSTR title) = 0;
- virtual HRESULT STDMETHODCALLTYPE containsItemForURLString(
- /* [in] */ void* urlCFString,
- /* [retval][out] */ BOOL* contains) = 0;
-};
+namespace WebCore {
+ class KURL;
+ class PageGroup;
+ class String;
+}
//-----------------------------------------------------------------------------
class WebPreferences;
-class WebHistory : public IWebHistory, IWebHistoryPrivate
-{
+class WebHistory : public IWebHistory {
public:
static WebHistory* createInstance();
-protected:
+private:
WebHistory();
~WebHistory();
/* [retval][out] */ int* limit);
// WebHistory
- static IWebHistoryPrivate* optionalSharedHistoryInternal();
- virtual HRESULT STDMETHODCALLTYPE addItemForURL(BSTR url, BSTR title);
- virtual HRESULT STDMETHODCALLTYPE containsItemForURLString(void* urlCFString, BOOL* contains);
+ static WebHistory* sharedHistory();
+ void addItem(const WebCore::KURL&, const WebCore::String&);
+ void addVisitedLinksToPageGroup(WebCore::PageGroup&);
-protected:
+private:
enum NotificationType
{
kWebHistoryItemsAddedNotification = 0,
BSTR getNotificationString(NotificationType notifyType);
HRESULT itemForURLString(CFStringRef urlString, IWebHistoryItem** item);
-protected:
ULONG m_refCount;
RetainPtr<CFMutableDictionaryRef> m_entriesByURL;
RetainPtr<CFMutableArrayRef> m_datesWithEntries;
RetainPtr<CFMutableArrayRef> m_entriesByDate;
COMPtr<WebPreferences> m_preferences;
- static IWebHistory* m_optionalSharedHistory;
};
#endif