Skip to content

Commit

Permalink
[iOS] Upstream DomAlteringLock.
Browse files Browse the repository at this point in the history
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
Show file tree
Hide file tree
Showing 3 changed files with 114 additions and 0 deletions.
64 changes: 64 additions & 0 deletions ios/chrome/browser/web/dom_altering_lock.h
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_
48 changes: 48 additions & 0 deletions ios/chrome/browser/web/dom_altering_lock.mm
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();
}
2 changes: 2 additions & 0 deletions ios/chrome/ios_chrome.gyp
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,8 @@
'browser/ui/ui_util.mm',
'browser/ui/uikit_ui_util.h',
'browser/ui/uikit_ui_util.mm',
'browser/web/dom_altering_lock.h',
'browser/web/dom_altering_lock.mm',
'browser/web_resource/ios_web_resource_service.cc',
'browser/web_resource/ios_web_resource_service.h',
],
Expand Down

0 comments on commit 88c11aa

Please sign in to comment.