forked from chromium/chromium
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
BUG=452490 Review URL: https://codereview.chromium.org/927373002 Cr-Commit-Position: refs/heads/master@{#316574}
- Loading branch information
droger
authored and
Commit bot
committed
Feb 17, 2015
1 parent
9c35d93
commit 88c11aa
Showing
3 changed files
with
114 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
// Copyright 2014 The Chromium Authors. All rights reserved. | ||
// Use of this source code is governed by a BSD-style license that can be | ||
// found in the LICENSE file. | ||
|
||
#ifndef IOS_CHROME_BROWSER_WEB_DOM_ALTERING_LOCK_H_ | ||
#define IOS_CHROME_BROWSER_WEB_DOM_ALTERING_LOCK_H_ | ||
|
||
#include "base/ios/block_types.h" | ||
#import "base/ios/weak_nsobject.h" | ||
#include "ios/web/public/web_state/web_state_user_data.h" | ||
|
||
namespace web { | ||
class WebState; | ||
} | ||
|
||
typedef void (^ProceduralBlockWithBool)(BOOL); | ||
|
||
// This protocol must be implemented by all classes which may alter the DOM tree | ||
// of a web page. Before altering the DOM, the class must call | ||
// DOMAlteringLock::Acquire() and can only proceed if the lock is really | ||
// acquired. | ||
// After restoring the DOM tree, the class must call DOMAlteringLock::Release(). | ||
@protocol DOMAltering<NSObject> | ||
|
||
// Method called when another class wants to acquire the lock. | ||
// Return YES if the class is ready to restore the DOM tree to its initial state | ||
// and release the lock. A call to |releaseDOMLockWithCompletionHandler:| | ||
// will follow to do the actual cleaning. | ||
// Return NO if the class wants to keep an exclusive access to the DOM tree. | ||
// Other features must account for the fact that they may not be able to acquire | ||
// a lock on the DOM and behave accordingly. | ||
- (BOOL)canReleaseDOMLock; | ||
|
||
// Method called when another class wants to acquire the lock. | ||
// The class must restore the DOM tree, call DOMAlteringLock::Release() and then | ||
// |completionHandler|. | ||
- (void)releaseDOMLockWithCompletionHandler:(ProceduralBlock)completionHandler; | ||
|
||
@end | ||
|
||
class DOMAlteringLock : public web::WebStateUserData<DOMAlteringLock> { | ||
public: | ||
DOMAlteringLock(web::WebState* web_state); | ||
|
||
// This method must be called before altering the DOM of the page. This will | ||
// ensure that only one class tries to alter the page at a time. | ||
// The completion handler is called with YES if the lock was acquired, or NO | ||
// if it could not. | ||
// This method must be called on the UI thread. | ||
void Acquire(id<DOMAltering> feature, ProceduralBlockWithBool lockAction); | ||
|
||
// Releases the lock on the DOM tree. | ||
// The lock is always released, even if it was acquired multiple times. | ||
// This method must be called on the UI thread. | ||
void Release(id<DOMAltering> feature); | ||
|
||
private: | ||
// DOMAltering object currently having the lock. | ||
base::WeakNSProtocol<id<DOMAltering>> current_dom_altering_feature_; | ||
|
||
~DOMAlteringLock() override; | ||
}; | ||
|
||
#endif // IOS_CHROME_BROWSER_WEB_DOM_ALTERING_LOCK_H_ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
// Copyright 2014 The Chromium Authors. All rights reserved. | ||
// Use of this source code is governed by a BSD-style license that can be | ||
// found in the LICENSE file. | ||
|
||
#import "ios/chrome/browser/web/dom_altering_lock.h" | ||
|
||
#include "base/logging.h" | ||
#include "ios/web/public/web_thread.h" | ||
|
||
DEFINE_WEB_STATE_USER_DATA_KEY(DOMAlteringLock); | ||
|
||
DOMAlteringLock::DOMAlteringLock(web::WebState* web_state) { | ||
} | ||
|
||
DOMAlteringLock::~DOMAlteringLock() { | ||
} | ||
|
||
void DOMAlteringLock::Acquire(id<DOMAltering> feature, | ||
ProceduralBlockWithBool lockAction) { | ||
DCHECK_CURRENTLY_ON_WEB_THREAD(web::WebThread::UI); | ||
if (current_dom_altering_feature_.get() == feature) { | ||
lockAction(YES); | ||
return; | ||
} | ||
if (current_dom_altering_feature_) { | ||
if (![current_dom_altering_feature_ canReleaseDOMLock]) { | ||
lockAction(NO); | ||
return; | ||
} | ||
[current_dom_altering_feature_ releaseDOMLockWithCompletionHandler:^() { | ||
DCHECK_CURRENTLY_ON_WEB_THREAD(web::WebThread::UI); | ||
DCHECK(current_dom_altering_feature_.get() == nil) | ||
<< "The lock must be released before calling the completion handler."; | ||
current_dom_altering_feature_.reset(feature); | ||
lockAction(YES); | ||
}]; | ||
return; | ||
} | ||
current_dom_altering_feature_.reset(feature); | ||
lockAction(YES); | ||
} | ||
|
||
// Release the lock on the DOM tree. | ||
void DOMAlteringLock::Release(id<DOMAltering> feature) { | ||
DCHECK_CURRENTLY_ON_WEB_THREAD(web::WebThread::UI); | ||
if (current_dom_altering_feature_.get() == feature) | ||
current_dom_altering_feature_.reset(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters