2010-12-10 16 views
8

WebView hỗ trợ, thông qua WebEditingDelegate, một cơ chế để đại biểu thực hiện hành vi tùy chỉnh cho một loạt các hành động mà WebView (hoặc số WebHTMLView) nhận được. Khi một hành động như:Làm cách nào tôi có thể phản ứng một cách có ý nghĩa với một thay đổiThuộc tính: ủy quyền truyền qua từ WebView?

-(void)changeAttributes:(id)sender 

nhận được trong WebHTMLView, nó được truyền thông qua các phương pháp đại biểu:

-(BOOL)webView:(WebView *)webView doCommandBySelector:(SEL)command 

Thật không may, cơ chế không quy định về vận chuyển của "sender" trong phương thức hành động gốc.

Đối với đại đa số các hành động, người gửi không quan trọng, nhưng đối với changeAttributes và changeFont, ví dụ: hợp đồng yêu cầu người nhận phải gọi số "sender". convertAttributes: hoặc convertFont:.

Đối với trường hợp changeFont, hóa ra là gọi số [[NSFontManager sharedFontManager] convertFont:] là đủ, ngẫu nhiên đây là nội dung người gửi.

Trong trường hợp changeAttributes, cụ thể khi gạch ngang được thay đổi, người gửi có thể là một lớp riêng "NSFontEffectsBox" có lẽ tương ứng với phần phụ của bảng phông chịu trách nhiệm thay đổi cài đặt gạch ngang/v.v.

Thật không may, gọi [[NSFontManager sharedFontManager] convertAttributes:] KHÔNG nhận được thay đổi thuộc tính dự kiến. Đây lá một đại biểu những người quan tâm trong việc thực hiện phương pháp này có ý nghĩa trong một chút của một câu hỏi hóc búa:

  1. WebKit không truyền đạt cho người gửi, vì vậy các đại biểu không thể làm cho các hợp đồng [sender convertAttributes:] gọi.

  2. Cuộc gọi changeAttributes: được gửi đến lớp WebKit riêng tư, WebHTMLView, không thể được phân loại thành, ví dụ: tùy chỉnh hành vi của changeAttributes:.

  3. Người gửi cho cuộc gọi changeAttributes:, NSFontEffectsBox, là một lớp riêng tư và không thể truy cập được, ví dụ: là [NSFontEffectsBox sharedFontEffectsBox].

Nói tóm lại: có vẻ như không có đường cho một nhà phát triển để có ý nghĩa ghi đè lên hành vi của changeAttributes: cho một WebView.

Bất kỳ ý tưởng nào?

+0

Ví dụ chính về Cách đặt câu hỏi. –

+0

Bạn có nghĩ rằng bạn có thể đăng các dấu vết ngăn xếp của các kịch bản khác nhau không? –

Trả lời

4

Đây là một điều ác. Một cặp phù hợp ác của hành động (không phải của họ đặc biệt là sạch hay lý tưởng) sẽ là:

  1. Do một số lắp ráp nội tuyến để nhìn lại lên stack để đọc các luận cứ gửi từ chồng của người gọi (hoặc gọi của người gọi, như trường hợp nên). Điều này tất nhiên giả định rằng người gửi được đặt trên ngăn xếp và không phải trong %eax khi cuộc gọi đến WebHTMLView được thực hiện. Điều đó sẽ luôn áp dụng cho mã PowerPC, vì vậy nó có khả năng không khởi động ở đó.

  2. Đặt danh mục trên WebHTMLView bằng phương thức có tên là __my_evil_hacky_nasty_ugly_changeAttributes_thing: và tại thời gian chạy sử dụng method_exchangeImplementations() từ thời gian chạy ObjC để trao đổi việc triển khai danh mục của bạn với chúng. Phương pháp của bạn trở thành changeAttributes: và các phương thức của chúng sẽ trở thành __my_evil_hacky_nasty_ugly_changeAttributes_thing:, sau đó bạn có thể gọi để chuyển sang cuộc gọi ban đầu.

Như tôi đã nói, không đặc biệt lý tưởng, nhưng thứ hai có lợi thế hỗ trợ thời gian chạy đầy đủ (tức là thời gian chạy được thiết kế rõ ràng để bạn làm điều này) và vì bạn đang tìm kiếm lớp học và phương pháp trong thời gian chạy, nó không chịu được. Thất bại trong trường hợp này sẽ đưa bạn trở lại một hình vuông tuy nhiên.

Thực sự nó cần một lỗi được ghi lại chống lại WebKit để chuyển chúng sang người gửi để làm cho nó có ý nghĩa. Phiên bản ghi đè của bạn có khả năng tìm kiếm phương thức -(BOOL)webView:(WebView*)webView doCommandBySelector:(SEL)selector sender:(id)sender và gọi đó nếu được tìm thấy, nếu không, chỉ cần gọi đến phương thức gốc. Đây là những gì mã của Apple nên làm, TBH.

+0

Cảm ơn bạn đã phản hồi. Tôi đã hy vọng tránh được cách tiếp cận khó khăn, vì tôi không chắc chắn về những rủi ro mà tôi đặt ra trong chừng mực Mac App Store của Apple cấm trên "API riêng". – danielpunkass

+0

Không nên có nguy cơ bị vấy bẩn. Tôi đã sử dụng nó trong các ứng dụng iOS mà không có vấn đề gì. Họ thậm chí không chạy 'chuỗi' trên các tệp nhị phân, vì vậy NSClassFromString (@" WebHTMLView ") không bị phát hiện. Thời gian chạy ObjC cũng công khai, vì vậy bạn có thể tự do sử dụng bất kỳ thứ gì trong đó-- tôi sử dụng nó để hoán đổi các phương thức bằng cách sử dụng '-performSelectorOnMainThread:' với 'dispatch_async()' phiên bản khi chạy trong một loạt các lớp, mặc dù chỉ trong các lớp học của riêng tôi. –

+0

FWIW Cuối cùng tôi đã báo cáo lỗi này: http://www.openradar.me/radar?id=4965931952373760 Tôi mất nhiều thời gian này vì tôi để cho vấn đề cơ bản rơi vào bên lề đường. Tôi nghĩ rằng tôi sẽ biến mất trong thời gian ngắn trong khi hy vọng cho một sửa chữa lâu dài hơn xuống đường. – danielpunkass

3

Bạn đã xem mã nguồn chưa?

WebHTMLView.mm

Tôi không thấy như thế nào -changeAttributes: đang kêu gọi -webView:doCommandBySelector:, như trong lớp này nó chỉ gọi là bên trong phương pháp -doCommandBySelector: riêng của mình.

- (void)changeAttributes:(id)sender 
{ 
    [self _applyStyleToSelection:[self _styleForAttributeChange:sender] withUndoAction:EditActionChangeAttributes]; 
} 


- (void)doCommandBySelector:(SEL)aSelector 
{ 
… 
    if (![[webView _editingDelegateForwarder] webView:webView doCommandBySelector:aSelector] && coreFrame) { 
… 
} 

Ngoài ra, tại sao bạn không thể phân lớp WebHTMLView? Có phải vì các hạn chế của Mac App Store trên API không? WebKit có được tính là riêng tư không? Tôi nghĩ đó là nguồn mở.

-Wil

+0

Wil, tôi không biết phiên bản của nguồn đó là gì. Trong phiên bản thân mới nhất mà tôi đang xem xét, nhiều phương thức hành động trong WebHTMLView có macro ở trên cùng, "COMMAND_PROLOGUE", điều này đảm nhiệm việc gửi thông điệp đến đại biểu. Theo như subclassing WebHTMLView đi, có một thực tế rằng nó là một API riêng, nhưng cũng WebView không tiếp xúc với các chi tiết thực hiện của xem tài liệu mà WebHTMLView được sử dụng cho. Theo như WebKit là nguồn mở, tôi không nghĩ rằng vấn đề. Apple muốn ngăn chặn sự phụ thuộc riêng tư vào hệ thống. – danielpunkass

Các vấn đề liên quan