Changeset 42447 in webkit
- Timestamp:
- Apr 13, 2009 12:50:32 PM (15 years ago)
- Location:
- trunk
- Files:
-
- 13 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r42442 r42447 1 2009-04-13 Sam Weinig <sam@webkit.org> 2 3 Reviewed by Oliver Hunt. 4 5 Update tests after moving showModalDialog from JSDOMWindowBase to 6 JSDOMWindow and slightly changing the behavior when showModalDialog 7 is not available, as is the case for DumpRenderTree. 8 9 * fast/dom/Window/window-function-frame-getter-precedence-expected.txt: 10 * fast/dom/Window/window-properties-expected.txt: 11 * platform/mac-leopard/fast/dom/Window/window-properties-expected.txt: 12 1 13 2009-04-13 Darin Fisher <darin@chromium.org> 2 14 -
trunk/LayoutTests/fast/dom/Window/window-function-frame-getter-precedence-expected.txt
r30157 r42447 31 31 PASS: typeof window.addEventListener should be object and is. 32 32 PASS: typeof window.removeEventListener should be object and is. 33 PASS: typeof window.showModalDialog should be object and is. 33 FAIL: typeof window.showModalDialog should be object but instead is undefined 34 34 PASS: typeof window.captureEvents should be object and is. 35 35 PASS: typeof window.releaseEvents should be object and is. -
trunk/LayoutTests/fast/dom/Window/window-properties-expected.txt
r42441 r42447 1758 1758 window.setInterval [function] 1759 1759 window.setTimeout [function] 1760 window.showModalDialog [undefined] 1760 1761 window.status [string] 1761 1762 window.statusbar [object BarInfo] -
trunk/LayoutTests/platform/mac-leopard/fast/dom/Window/window-properties-expected.txt
r42441 r42447 1753 1753 window.setInterval [function] 1754 1754 window.setTimeout [function] 1755 window.showModalDialog [undefined] 1755 1756 window.status [string] 1756 1757 window.statusbar [object BarInfo] -
trunk/WebCore/ChangeLog
r42446 r42447 1 2009-04-13 Sam Weinig <sam@webkit.org> 2 3 Reviewed by Oliver Hunt. 4 5 Move open and showModalDialog functions out of JSDOMWindowBase 6 and into JSDOMWindow by partially generating them. 7 8 This slightly changes the behavior of getting window.showModalDialog 9 when the embedding app does not support it to return undefined regardless 10 of shadowing. This should not be an issue in a practice, but will be addressed 11 when we add a generic way to handle runtime specialization of property 12 access. 13 14 * DerivedSources.make: Remove JSDOMWindowBase.lut.h 15 * WebCore.xcodeproj/project.pbxproj: Ditto. 16 * bindings/js/JSDOMWindowBase.cpp: 17 (WebCore::): 18 (WebCore::JSDOMWindowBase::getOwnPropertySlot): Move canShowModalDialog check from 19 here to JSDOMWindow::customGetOwnPropertySlot. 20 (WebCore::JSDOMWindowBase::put): Remove dead code. 21 * bindings/js/JSDOMWindowCustom.cpp: 22 (WebCore::createWindow): 23 (WebCore::JSDOMWindow::open): 24 (WebCore::JSDOMWindow::showModalDialog): 25 * bindings/js/JSDOMWindowCustom.h: 26 (WebCore::JSDOMWindow::customGetOwnPropertySlot): 27 * page/DOMWindow.cpp: 28 (WebCore::DOMWindow::parseModalDialogFeatures): Move from JSDOMWindowBase. 29 (WebCore::DOMWindow::allowPopUp): Ditto. 30 (WebCore::DOMWindow::canShowModalDialog): Ditto. 31 (WebCore::DOMWindow::canShowModalDialogNow): Ditto. 32 * page/DOMWindow.h: 33 * page/DOMWindow.idl: 34 1 35 2009-04-13 Geoffrey Garen <ggaren@apple.com> 2 36 -
trunk/WebCore/DerivedSources.make
r42361 r42447 387 387 $(filter-out JSEventListener.h JSEventTarget.h JSRGBColor.h,$(DOM_CLASSES:%=JS%.h)) \ 388 388 \ 389 JSDOMWindowBase.lut.h \390 389 JSRGBColor.lut.h \ 391 390 JSWorkerContextBase.lut.h \ -
trunk/WebCore/WebCore.xcodeproj/project.pbxproj
r42437 r42447 4258 4258 BCEFE1EA0DCA5F6400739219 /* JSXSLTProcessor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BCEFE1E80DCA5F6400739219 /* JSXSLTProcessor.cpp */; }; 4259 4259 BCEFE1EB0DCA5F6400739219 /* JSXSLTProcessor.h in Headers */ = {isa = PBXBuildFile; fileRef = BCEFE1E90DCA5F6400739219 /* JSXSLTProcessor.h */; }; 4260 BCF937E70E8B2E95005C7AB7 /* JSDOMWindowBase.lut.h in Headers */ = {isa = PBXBuildFile; fileRef = BCF937E60E8B2E95005C7AB7 /* JSDOMWindowBase.lut.h */; };4261 4260 BCFB2E5E0979E46400BA703D /* CachedResourceClient.h in Headers */ = {isa = PBXBuildFile; fileRef = BCFB2E5D0979E46400BA703D /* CachedResourceClient.h */; settings = {ATTRIBUTES = (Private, ); }; }; 4262 4261 BCFB2F76097A2E1A00BA703D /* Arena.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BCFB2F74097A2E1A00BA703D /* Arena.cpp */; }; … … 9060 9059 BCEFE1E80DCA5F6400739219 /* JSXSLTProcessor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSXSLTProcessor.cpp; sourceTree = "<group>"; }; 9061 9060 BCEFE1E90DCA5F6400739219 /* JSXSLTProcessor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSXSLTProcessor.h; sourceTree = "<group>"; }; 9062 BCF937E60E8B2E95005C7AB7 /* JSDOMWindowBase.lut.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSDOMWindowBase.lut.h; sourceTree = "<group>"; };9063 9061 BCFB2E5D0979E46400BA703D /* CachedResourceClient.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CachedResourceClient.h; sourceTree = "<group>"; }; 9064 9062 BCFB2F74097A2E1A00BA703D /* Arena.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Arena.cpp; sourceTree = "<group>"; }; … … 13609 13607 1403BA0B09EB18C700797C7F /* JSDOMWindow.cpp */, 13610 13608 1403BA0E09EB18F800797C7F /* JSDOMWindow.h */, 13611 BCF937E60E8B2E95005C7AB7 /* JSDOMWindowBase.lut.h */,13612 13609 BC94D14C0C275C68006BC617 /* JSHistory.cpp */, 13613 13610 BC94D14D0C275C68006BC617 /* JSHistory.h */, … … 15779 15776 E10BB3860F14B95000560E13 /* JSDOMStringList.h in Headers */, 15780 15777 BC6932740D7E293900AE44D1 /* JSDOMWindowBase.h in Headers */, 15781 BCF937E70E8B2E95005C7AB7 /* JSDOMWindowBase.lut.h in Headers */,15782 15778 652FBBBC0DE27CB60001D386 /* JSDOMWindowCustom.h in Headers */, 15783 15779 BCBFB53D0DCD29CF0019B3E5 /* JSDOMWindowShell.h in Headers */, -
trunk/WebCore/bindings/js/JSDOMWindowBase.cpp
r42430 r42447 29 29 #include "DOMWindow.h" 30 30 #include "Element.h" 31 #include "FloatRect.h"32 31 #include "Frame.h" 33 #include "FrameLoadRequest.h"34 32 #include "HTMLDocument.h" 35 33 #include "InspectorController.h" 36 34 #include "JSDOMWindowCustom.h" 37 #include "JSEvent.h"38 35 #include "JSHTMLCollection.h" 39 36 #include "JSNode.h" 40 37 #include "Logging.h" 41 38 #include "Page.h" 42 #include "PlatformScreen.h"43 #include "RenderView.h"44 39 #include "ScheduledAction.h" 45 40 #include "ScriptController.h" 46 41 #include "SecurityOrigin.h" 47 42 #include "Settings.h" 48 #include "WindowFeatures.h"49 43 #include <runtime/JSLock.h> 50 #include <wtf/MathExtras.h>51 44 52 45 using namespace JSC; 53 46 54 static JSValuePtr windowProtoFuncOpen(ExecState*, JSObject*, JSValuePtr, const ArgList&);55 static JSValuePtr windowProtoFuncShowModalDialog(ExecState*, JSObject*, JSValuePtr, const ArgList&);56 57 #include "JSDOMWindowBase.lut.h"58 59 47 namespace WebCore { 60 48 61 49 ////////////////////// JSDOMWindowBase Object //////////////////////// 62 50 63 const ClassInfo JSDOMWindowBase::s_info = { "Window", 0, &JSDOMWindowBaseTable, 0 }; 64 65 /* 66 @begin JSDOMWindowBaseTable 67 # -- Functions -- 68 open windowProtoFuncOpen DontDelete|Function 3 69 showModalDialog windowProtoFuncShowModalDialog DontDelete|Function 1 70 @end 71 */ 51 const ClassInfo JSDOMWindowBase::s_info = { "Window", 0, 0, 0 }; 72 52 73 53 JSDOMWindowBase::JSDOMWindowBaseData::JSDOMWindowBaseData(PassRefPtr<DOMWindow> window, JSDOMWindowShell* shell) … … 103 83 { 104 84 return d()->impl->document(); 105 }106 107 static bool allowPopUp(ExecState* exec)108 {109 Frame* frame = asJSDOMWindow(exec->dynamicGlobalObject())->impl()->frame();110 111 ASSERT(frame);112 if (frame->script()->processingUserGesture())113 return true;114 Settings* settings = frame->settings();115 return settings && settings->JavaScriptCanOpenWindowsAutomatically();116 }117 118 static HashMap<String, String> parseModalDialogFeatures(const String& featuresArg)119 {120 HashMap<String, String> map;121 122 Vector<String> features;123 featuresArg.split(';', features);124 Vector<String>::const_iterator end = features.end();125 for (Vector<String>::const_iterator it = features.begin(); it != end; ++it) {126 String s = *it;127 int pos = s.find('=');128 int colonPos = s.find(':');129 if (pos >= 0 && colonPos >= 0)130 continue; // ignore any strings that have both = and :131 if (pos < 0)132 pos = colonPos;133 if (pos < 0) {134 // null string for value means key without value135 map.set(s.stripWhiteSpace().lower(), String());136 } else {137 String key = s.left(pos).stripWhiteSpace().lower();138 String val = s.substring(pos + 1).stripWhiteSpace().lower();139 int spacePos = val.find(' ');140 if (spacePos != -1)141 val = val.left(spacePos);142 map.set(key, val);143 }144 }145 146 return map;147 }148 149 static Frame* createWindow(ExecState* exec, Frame* openerFrame, const String& url,150 const String& frameName, const WindowFeatures& windowFeatures, JSValuePtr dialogArgs)151 {152 Frame* activeFrame = asJSDOMWindow(exec->dynamicGlobalObject())->impl()->frame();153 ASSERT(activeFrame);154 155 ResourceRequest request;156 157 request.setHTTPReferrer(activeFrame->loader()->outgoingReferrer());158 FrameLoader::addHTTPOriginIfNeeded(request, activeFrame->loader()->outgoingOrigin());159 FrameLoadRequest frameRequest(request, frameName);160 161 // FIXME: It's much better for client API if a new window starts with a URL, here where we162 // know what URL we are going to open. Unfortunately, this code passes the empty string163 // for the URL, but there's a reason for that. Before loading we have to set up the opener,164 // openedByDOM, and dialogArguments values. Also, to decide whether to use the URL we currently165 // do an allowsAccessFrom call using the window we create, which can't be done before creating it.166 // We'd have to resolve all those issues to pass the URL instead of "".167 168 bool created;169 // We pass in the opener frame here so it can be used for looking up the frame name, in case the active frame170 // is different from the opener frame, and the name references a frame relative to the opener frame, for example171 // "_self" or "_parent".172 Frame* newFrame = activeFrame->loader()->createWindow(openerFrame->loader(), frameRequest, windowFeatures, created);173 if (!newFrame)174 return 0;175 176 newFrame->loader()->setOpener(openerFrame);177 newFrame->loader()->setOpenedByDOM();178 179 JSDOMWindow* newWindow = toJSDOMWindow(newFrame);180 181 if (dialogArgs)182 newWindow->putDirect(Identifier(exec, "dialogArguments"), dialogArgs);183 184 if (!protocolIs(url, "javascript") || newWindow->allowsAccessFrom(exec)) {185 KURL completedURL = url.isEmpty() ? KURL("") : activeFrame->document()->completeURL(url);186 bool userGesture = activeFrame->script()->processingUserGesture();187 188 if (created)189 newFrame->loader()->changeLocation(completedURL, activeFrame->loader()->outgoingReferrer(), false, false, userGesture);190 else if (!url.isEmpty())191 newFrame->loader()->scheduleLocationChange(completedURL.string(), activeFrame->loader()->outgoingReferrer(), !activeFrame->script()->anyPageIsProcessingUserGesture(), false, userGesture);192 }193 194 return newFrame;195 }196 197 static bool canShowModalDialog(const Frame* frame)198 {199 if (!frame)200 return false;201 202 Page* page = frame->page();203 if (!page)204 return false;205 206 return page->chrome()->canRunModal();207 }208 209 static bool canShowModalDialogNow(const Frame* frame)210 {211 if (!frame)212 return false;213 214 Page* page = frame->page();215 if (!page)216 return false;217 218 return page->chrome()->canRunModalNow();219 }220 221 static JSValuePtr showModalDialog(ExecState* exec, Frame* frame, const String& url, JSValuePtr dialogArgs, const String& featureArgs)222 {223 if (!canShowModalDialogNow(frame) || !allowPopUp(exec))224 return jsUndefined();225 226 const HashMap<String, String> features = parseModalDialogFeatures(featureArgs);227 228 const bool trusted = false;229 230 // The following features from Microsoft's documentation are not implemented:231 // - default font settings232 // - width, height, left, and top specified in units other than "px"233 // - edge (sunken or raised, default is raised)234 // - dialogHide: trusted && boolFeature(features, "dialoghide"), makes dialog hide when you print235 // - help: boolFeature(features, "help", true), makes help icon appear in dialog (what does it do on Windows?)236 // - unadorned: trusted && boolFeature(features, "unadorned");237 238 if (!frame)239 return jsUndefined();240 241 FloatRect screenRect = screenAvailableRect(frame->view());242 243 WindowFeatures wargs;244 wargs.width = WindowFeatures::floatFeature(features, "dialogwidth", 100, screenRect.width(), 620); // default here came from frame size of dialog in MacIE245 wargs.widthSet = true;246 wargs.height = WindowFeatures::floatFeature(features, "dialogheight", 100, screenRect.height(), 450); // default here came from frame size of dialog in MacIE247 wargs.heightSet = true;248 249 wargs.x = WindowFeatures::floatFeature(features, "dialogleft", screenRect.x(), screenRect.right() - wargs.width, -1);250 wargs.xSet = wargs.x > 0;251 wargs.y = WindowFeatures::floatFeature(features, "dialogtop", screenRect.y(), screenRect.bottom() - wargs.height, -1);252 wargs.ySet = wargs.y > 0;253 254 if (WindowFeatures::boolFeature(features, "center", true)) {255 if (!wargs.xSet) {256 wargs.x = screenRect.x() + (screenRect.width() - wargs.width) / 2;257 wargs.xSet = true;258 }259 if (!wargs.ySet) {260 wargs.y = screenRect.y() + (screenRect.height() - wargs.height) / 2;261 wargs.ySet = true;262 }263 }264 265 wargs.dialog = true;266 wargs.resizable = WindowFeatures::boolFeature(features, "resizable");267 wargs.scrollbarsVisible = WindowFeatures::boolFeature(features, "scroll", true);268 wargs.statusBarVisible = WindowFeatures::boolFeature(features, "status", !trusted);269 wargs.menuBarVisible = false;270 wargs.toolBarVisible = false;271 wargs.locationBarVisible = false;272 wargs.fullscreen = false;273 274 Frame* dialogFrame = createWindow(exec, frame, url, "", wargs, dialogArgs);275 if (!dialogFrame)276 return jsUndefined();277 278 JSDOMWindow* dialogWindow = toJSDOMWindow(dialogFrame);279 280 // Get the return value either just before clearing the dialog window's281 // properties (in JSDOMWindowBase::clear), or when on return from runModal.282 JSValuePtr returnValue = noValue();283 dialogWindow->setReturnValueSlot(&returnValue);284 dialogFrame->page()->chrome()->runModal();285 dialogWindow->setReturnValueSlot(0);286 287 // If we don't have a return value, get it now.288 // Either JSDOMWindowBase::clear was not called yet, or there was no return value,289 // and in that case, there's no harm in trying again (no benefit either).290 if (!returnValue)291 returnValue = dialogWindow->getDirect(Identifier(exec, "returnValue"));292 293 return returnValue ? returnValue : jsUndefined();294 85 } 295 86 … … 327 118 if (impl()->frame()->tree()->child(propertyName)) { 328 119 slot.setCustom(this, childFrameGetter); 329 return true;330 }331 332 const HashEntry* entry = JSDOMWindowBaseTable.entry(exec, propertyName);333 if (entry) {334 if (entry->attributes() & Function) {335 if (entry->function() == windowProtoFuncShowModalDialog) {336 if (!canShowModalDialog(impl()->frame()))337 return false;338 }339 if (allowsAccessFrom(exec))340 setUpStaticFunctionSlot(exec, entry, this, propertyName, slot);341 else342 slot.setUndefined();343 } else344 slot.setCustom(this, entry->propertyGetter());345 120 return true; 346 121 } … … 388 163 void JSDOMWindowBase::put(ExecState* exec, const Identifier& propertyName, JSValuePtr value, PutPropertySlot& slot) 389 164 { 390 const HashEntry* entry = JSDOMWindowBaseTable.entry(exec, propertyName);391 if (entry) {392 if (entry->attributes() & Function) {393 if (allowsAccessFrom(exec))394 Base::put(exec, propertyName, value, slot);395 return;396 }397 if (entry->attributes() & ReadOnly)398 return;399 }400 401 165 if (allowsAccessFrom(exec)) 402 166 Base::put(exec, propertyName, value, slot); … … 510 274 } 511 275 512 } // namespace WebCore513 514 using namespace WebCore;515 516 JSValuePtr windowProtoFuncOpen(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)517 {518 JSDOMWindow* window = toJSDOMWindow(thisValue);519 if (!window)520 return throwError(exec, TypeError);521 if (!window->allowsAccessFrom(exec))522 return jsUndefined();523 524 Frame* frame = window->impl()->frame();525 if (!frame)526 return jsUndefined();527 Frame* activeFrame = asJSDOMWindow(exec->dynamicGlobalObject())->impl()->frame();528 if (!activeFrame)529 return jsUndefined();530 531 Page* page = frame->page();532 533 String urlString = valueToStringWithUndefinedOrNullCheck(exec, args.at(exec, 0));534 AtomicString frameName = args.at(exec, 1).isUndefinedOrNull() ? "_blank" : AtomicString(args.at(exec, 1).toString(exec));535 536 // Because FrameTree::find() returns true for empty strings, we must check for empty framenames.537 // Otherwise, illegitimate window.open() calls with no name will pass right through the popup blocker.538 if (!allowPopUp(exec) && (frameName.isEmpty() || !frame->tree()->find(frameName)))539 return jsUndefined();540 541 // Get the target frame for the special cases of _top and _parent. In those542 // cases, we can schedule a location change right now and return early.543 bool topOrParent = false;544 if (frameName == "_top") {545 frame = frame->tree()->top();546 topOrParent = true;547 } else if (frameName == "_parent") {548 if (Frame* parent = frame->tree()->parent())549 frame = parent;550 topOrParent = true;551 }552 if (topOrParent) {553 if (!activeFrame->loader()->shouldAllowNavigation(frame))554 return jsUndefined();555 556 String completedURL;557 if (!urlString.isEmpty())558 completedURL = activeFrame->document()->completeURL(urlString).string();559 560 const JSDOMWindow* targetedWindow = toJSDOMWindow(frame);561 if (!completedURL.isEmpty() && (!protocolIs(completedURL, "javascript") || (targetedWindow && targetedWindow->allowsAccessFrom(exec)))) {562 bool userGesture = activeFrame->script()->processingUserGesture();563 frame->loader()->scheduleLocationChange(completedURL, activeFrame->loader()->outgoingReferrer(), !activeFrame->script()->anyPageIsProcessingUserGesture(), false, userGesture);564 }565 return toJS(exec, frame->domWindow());566 }567 568 // In the case of a named frame or a new window, we'll use the createWindow() helper569 WindowFeatures windowFeatures(valueToStringWithUndefinedOrNullCheck(exec, args.at(exec, 2)));570 FloatRect windowRect(windowFeatures.xSet ? windowFeatures.x : 0, windowFeatures.ySet ? windowFeatures.y : 0,571 windowFeatures.widthSet ? windowFeatures.width : 0, windowFeatures.heightSet ? windowFeatures.height : 0);572 DOMWindow::adjustWindowRect(screenAvailableRect(page ? page->mainFrame()->view() : 0), windowRect, windowRect);573 574 windowFeatures.x = windowRect.x();575 windowFeatures.y = windowRect.y();576 windowFeatures.height = windowRect.height();577 windowFeatures.width = windowRect.width();578 579 frame = createWindow(exec, frame, urlString, frameName, windowFeatures, noValue());580 581 if (!frame)582 return jsUndefined();583 584 return toJS(exec, frame->domWindow()); // global object585 }586 587 JSValuePtr windowProtoFuncShowModalDialog(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)588 {589 JSDOMWindow* window = toJSDOMWindow(thisValue);590 if (!window)591 return throwError(exec, TypeError);592 if (!window->allowsAccessFrom(exec))593 return jsUndefined();594 595 Frame* frame = window->impl()->frame();596 if (!frame)597 return jsUndefined();598 599 return showModalDialog(exec, frame, valueToStringWithUndefinedOrNullCheck(exec, args.at(exec, 0)), args.at(exec, 1), valueToStringWithUndefinedOrNullCheck(exec, args.at(exec, 2)));600 }601 602 namespace WebCore {603 604 276 void JSDOMWindowBase::setReturnValueSlot(JSValuePtr* slot) 605 277 { 606 278 d()->returnValueSlot = slot; 607 279 } 608 609 ////////////////////// timeouts ////////////////////////610 280 611 281 int JSDOMWindowBase::installTimeout(ScheduledAction* a, int t, bool singleShot) -
trunk/WebCore/bindings/js/JSDOMWindowCustom.cpp
r42446 r42447 26 26 #include "Document.h" 27 27 #include "ExceptionCode.h" 28 #include "FloatRect.h" 28 29 #include "Frame.h" 30 #include "FrameLoadRequest.h" 29 31 #include "FrameLoader.h" 30 32 #include "FrameTree.h" 33 #include "FrameView.h" 31 34 #include "History.h" 32 35 #include "JSAudioConstructor.h" … … 48 51 #include "MediaPlayer.h" 49 52 #include "MessagePort.h" 53 #include "Page.h" 54 #include "PlatformScreen.h" 50 55 #include "ScriptController.h" 51 56 #include "Settings.h" 57 #include "WindowFeatures.h" 52 58 #include <runtime/JSObject.h> 53 59 #include <runtime/PrototypeFunction.h> … … 145 151 } 146 152 153 // Custom Attributes 154 147 155 JSValuePtr JSDOMWindow::history(ExecState* exec) const 148 156 { … … 263 271 #endif 264 272 273 // Custom functions 274 275 // Helper for window.open() and window.showModalDialog() 276 static Frame* createWindow(ExecState* exec, Frame* activeFrame, Frame* openerFrame, 277 const String& url, const String& frameName, 278 const WindowFeatures& windowFeatures, JSValuePtr dialogArgs) 279 { 280 ASSERT(activeFrame); 281 282 ResourceRequest request; 283 284 request.setHTTPReferrer(activeFrame->loader()->outgoingReferrer()); 285 FrameLoader::addHTTPOriginIfNeeded(request, activeFrame->loader()->outgoingOrigin()); 286 FrameLoadRequest frameRequest(request, frameName); 287 288 // FIXME: It's much better for client API if a new window starts with a URL, here where we 289 // know what URL we are going to open. Unfortunately, this code passes the empty string 290 // for the URL, but there's a reason for that. Before loading we have to set up the opener, 291 // openedByDOM, and dialogArguments values. Also, to decide whether to use the URL we currently 292 // do an allowsAccessFrom call using the window we create, which can't be done before creating it. 293 // We'd have to resolve all those issues to pass the URL instead of "". 294 295 bool created; 296 // We pass in the opener frame here so it can be used for looking up the frame name, in case the active frame 297 // is different from the opener frame, and the name references a frame relative to the opener frame, for example 298 // "_self" or "_parent". 299 Frame* newFrame = activeFrame->loader()->createWindow(openerFrame->loader(), frameRequest, windowFeatures, created); 300 if (!newFrame) 301 return 0; 302 303 newFrame->loader()->setOpener(openerFrame); 304 newFrame->loader()->setOpenedByDOM(); 305 306 JSDOMWindow* newWindow = toJSDOMWindow(newFrame); 307 308 if (dialogArgs) 309 newWindow->putDirect(Identifier(exec, "dialogArguments"), dialogArgs); 310 311 if (!protocolIs(url, "javascript") || newWindow->allowsAccessFrom(exec)) { 312 KURL completedURL = url.isEmpty() ? KURL("") : activeFrame->document()->completeURL(url); 313 bool userGesture = activeFrame->script()->processingUserGesture(); 314 315 if (created) 316 newFrame->loader()->changeLocation(completedURL, activeFrame->loader()->outgoingReferrer(), false, false, userGesture); 317 else if (!url.isEmpty()) 318 newFrame->loader()->scheduleLocationChange(completedURL.string(), activeFrame->loader()->outgoingReferrer(), !activeFrame->script()->anyPageIsProcessingUserGesture(), false, userGesture); 319 } 320 321 return newFrame; 322 } 323 324 JSValuePtr JSDOMWindow::open(ExecState* exec, const ArgList& args) 325 { 326 Frame* frame = impl()->frame(); 327 if (!frame) 328 return jsUndefined(); 329 Frame* activeFrame = asJSDOMWindow(exec->dynamicGlobalObject())->impl()->frame(); 330 if (!activeFrame) 331 return jsUndefined(); 332 333 Page* page = frame->page(); 334 335 String urlString = valueToStringWithUndefinedOrNullCheck(exec, args.at(exec, 0)); 336 AtomicString frameName = args.at(exec, 1).isUndefinedOrNull() ? "_blank" : AtomicString(args.at(exec, 1).toString(exec)); 337 338 // Because FrameTree::find() returns true for empty strings, we must check for empty framenames. 339 // Otherwise, illegitimate window.open() calls with no name will pass right through the popup blocker. 340 if (!DOMWindow::allowPopUp(activeFrame) && (frameName.isEmpty() || !frame->tree()->find(frameName))) 341 return jsUndefined(); 342 343 // Get the target frame for the special cases of _top and _parent. In those 344 // cases, we can schedule a location change right now and return early. 345 bool topOrParent = false; 346 if (frameName == "_top") { 347 frame = frame->tree()->top(); 348 topOrParent = true; 349 } else if (frameName == "_parent") { 350 if (Frame* parent = frame->tree()->parent()) 351 frame = parent; 352 topOrParent = true; 353 } 354 if (topOrParent) { 355 if (!activeFrame->loader()->shouldAllowNavigation(frame)) 356 return jsUndefined(); 357 358 String completedURL; 359 if (!urlString.isEmpty()) 360 completedURL = activeFrame->document()->completeURL(urlString).string(); 361 362 const JSDOMWindow* targetedWindow = toJSDOMWindow(frame); 363 if (!completedURL.isEmpty() && (!protocolIs(completedURL, "javascript") || (targetedWindow && targetedWindow->allowsAccessFrom(exec)))) { 364 bool userGesture = activeFrame->script()->processingUserGesture(); 365 frame->loader()->scheduleLocationChange(completedURL, activeFrame->loader()->outgoingReferrer(), !activeFrame->script()->anyPageIsProcessingUserGesture(), false, userGesture); 366 } 367 return toJS(exec, frame->domWindow()); 368 } 369 370 // In the case of a named frame or a new window, we'll use the createWindow() helper 371 WindowFeatures windowFeatures(valueToStringWithUndefinedOrNullCheck(exec, args.at(exec, 2))); 372 FloatRect windowRect(windowFeatures.xSet ? windowFeatures.x : 0, windowFeatures.ySet ? windowFeatures.y : 0, 373 windowFeatures.widthSet ? windowFeatures.width : 0, windowFeatures.heightSet ? windowFeatures.height : 0); 374 DOMWindow::adjustWindowRect(screenAvailableRect(page ? page->mainFrame()->view() : 0), windowRect, windowRect); 375 376 windowFeatures.x = windowRect.x(); 377 windowFeatures.y = windowRect.y(); 378 windowFeatures.height = windowRect.height(); 379 windowFeatures.width = windowRect.width(); 380 381 frame = createWindow(exec, activeFrame, frame, urlString, frameName, windowFeatures, noValue()); 382 383 if (!frame) 384 return jsUndefined(); 385 386 return toJS(exec, frame->domWindow()); 387 } 388 389 JSValuePtr JSDOMWindow::showModalDialog(ExecState* exec, const ArgList& args) 390 { 391 Frame* frame = impl()->frame(); 392 if (!frame) 393 return jsUndefined(); 394 395 Frame* activeFrame = asJSDOMWindow(exec->dynamicGlobalObject())->impl()->frame(); 396 397 if (!DOMWindow::canShowModalDialogNow(frame) || !DOMWindow::allowPopUp(activeFrame)) 398 return jsUndefined(); 399 400 String url = valueToStringWithUndefinedOrNullCheck(exec, args.at(exec, 0)); 401 JSValuePtr dialogArgs = args.at(exec, 1); 402 String featureArgs = valueToStringWithUndefinedOrNullCheck(exec, args.at(exec, 2)); 403 404 HashMap<String, String> features; 405 DOMWindow::parseModalDialogFeatures(featureArgs, features); 406 407 const bool trusted = false; 408 409 // The following features from Microsoft's documentation are not implemented: 410 // - default font settings 411 // - width, height, left, and top specified in units other than "px" 412 // - edge (sunken or raised, default is raised) 413 // - dialogHide: trusted && boolFeature(features, "dialoghide"), makes dialog hide when you print 414 // - help: boolFeature(features, "help", true), makes help icon appear in dialog (what does it do on Windows?) 415 // - unadorned: trusted && boolFeature(features, "unadorned"); 416 417 FloatRect screenRect = screenAvailableRect(frame->view()); 418 419 WindowFeatures wargs; 420 wargs.width = WindowFeatures::floatFeature(features, "dialogwidth", 100, screenRect.width(), 620); // default here came from frame size of dialog in MacIE 421 wargs.widthSet = true; 422 wargs.height = WindowFeatures::floatFeature(features, "dialogheight", 100, screenRect.height(), 450); // default here came from frame size of dialog in MacIE 423 wargs.heightSet = true; 424 425 wargs.x = WindowFeatures::floatFeature(features, "dialogleft", screenRect.x(), screenRect.right() - wargs.width, -1); 426 wargs.xSet = wargs.x > 0; 427 wargs.y = WindowFeatures::floatFeature(features, "dialogtop", screenRect.y(), screenRect.bottom() - wargs.height, -1); 428 wargs.ySet = wargs.y > 0; 429 430 if (WindowFeatures::boolFeature(features, "center", true)) { 431 if (!wargs.xSet) { 432 wargs.x = screenRect.x() + (screenRect.width() - wargs.width) / 2; 433 wargs.xSet = true; 434 } 435 if (!wargs.ySet) { 436 wargs.y = screenRect.y() + (screenRect.height() - wargs.height) / 2; 437 wargs.ySet = true; 438 } 439 } 440 441 wargs.dialog = true; 442 wargs.resizable = WindowFeatures::boolFeature(features, "resizable"); 443 wargs.scrollbarsVisible = WindowFeatures::boolFeature(features, "scroll", true); 444 wargs.statusBarVisible = WindowFeatures::boolFeature(features, "status", !trusted); 445 wargs.menuBarVisible = false; 446 wargs.toolBarVisible = false; 447 wargs.locationBarVisible = false; 448 wargs.fullscreen = false; 449 450 Frame* dialogFrame = createWindow(exec, activeFrame, frame, url, "", wargs, dialogArgs); 451 if (!dialogFrame) 452 return jsUndefined(); 453 454 JSDOMWindow* dialogWindow = toJSDOMWindow(dialogFrame); 455 456 // Get the return value either just before clearing the dialog window's 457 // properties (in JSDOMWindowBase::clear), or when on return from runModal. 458 JSValuePtr returnValue = noValue(); 459 dialogWindow->setReturnValueSlot(&returnValue); 460 dialogFrame->page()->chrome()->runModal(); 461 dialogWindow->setReturnValueSlot(0); 462 463 // If we don't have a return value, get it now. 464 // Either JSDOMWindowBase::clear was not called yet, or there was no return value, 465 // and in that case, there's no harm in trying again (no benefit either). 466 if (!returnValue) 467 returnValue = dialogWindow->getDirect(Identifier(exec, "returnValue")); 468 469 return returnValue ? returnValue : jsUndefined(); 470 } 471 265 472 JSValuePtr JSDOMWindow::postMessage(ExecState* exec, const ArgList& args) 266 473 { -
trunk/WebCore/bindings/js/JSDOMWindowCustom.h
r42201 r42447 107 107 return true; 108 108 } 109 } else if (entry->function() == jsDOMWindowPrototypeFunctionShowModalDialog) { 110 if (!DOMWindow::canShowModalDialog(impl()->frame())) { 111 slot.setUndefined(); 112 return true; 113 } 109 114 } 110 115 } -
trunk/WebCore/page/DOMWindow.cpp
r42446 r42447 145 145 } 146 146 147 void DOMWindow::parseModalDialogFeatures(const String& featuresArg, HashMap<String, String>& map) 148 { 149 Vector<String> features; 150 featuresArg.split(';', features); 151 Vector<String>::const_iterator end = features.end(); 152 for (Vector<String>::const_iterator it = features.begin(); it != end; ++it) { 153 String s = *it; 154 int pos = s.find('='); 155 int colonPos = s.find(':'); 156 if (pos >= 0 && colonPos >= 0) 157 continue; // ignore any strings that have both = and : 158 if (pos < 0) 159 pos = colonPos; 160 if (pos < 0) { 161 // null string for value means key without value 162 map.set(s.stripWhiteSpace().lower(), String()); 163 } else { 164 String key = s.left(pos).stripWhiteSpace().lower(); 165 String val = s.substring(pos + 1).stripWhiteSpace().lower(); 166 int spacePos = val.find(' '); 167 if (spacePos != -1) 168 val = val.left(spacePos); 169 map.set(key, val); 170 } 171 } 172 } 173 174 bool DOMWindow::allowPopUp(Frame* activeFrame) 175 { 176 ASSERT(activeFrame); 177 if (activeFrame->script()->processingUserGesture()) 178 return true; 179 Settings* settings = activeFrame->settings(); 180 return settings && settings->JavaScriptCanOpenWindowsAutomatically(); 181 } 182 183 bool DOMWindow::canShowModalDialog(const Frame* frame) 184 { 185 if (!frame) 186 return false; 187 Page* page = frame->page(); 188 if (!page) 189 return false; 190 return page->chrome()->canRunModal(); 191 } 192 193 bool DOMWindow::canShowModalDialogNow(const Frame* frame) 194 { 195 if (!frame) 196 return false; 197 Page* page = frame->page(); 198 if (!page) 199 return false; 200 return page->chrome()->canRunModalNow(); 201 } 202 147 203 DOMWindow::DOMWindow(Frame* frame) 148 204 : m_frame(frame) -
trunk/WebCore/page/DOMWindow.h
r42446 r42447 86 86 87 87 static void adjustWindowRect(const FloatRect& screen, FloatRect& window, const FloatRect& pendingChanges); 88 static void parseModalDialogFeatures(const String& featuresArg, HashMap<String, String>& map); 89 90 static bool allowPopUp(Frame* activeFrame); 91 static bool canShowModalDialog(const Frame*); 92 static bool canShowModalDialogNow(const Frame*); 88 93 89 94 // DOM Level 0 -
trunk/WebCore/page/DOMWindow.idl
r42441 r42447 70 70 void print(); 71 71 void stop(); 72 73 [Custom] DOMWindow open(in DOMString url, 74 in DOMString name, 75 in [Optional] DOMString options); 76 77 [Custom] DOMObject showModalDialog(in DOMString url, 78 in [Optional] DOMObject dialogArgs, 79 in [Optional] DOMString featureArgs); 72 80 73 81 void alert(in DOMString message); … … 467 475 468 476 #if defined(V8_BINDING) 469 // These were implemented in JSCDOMWindowBase and not moved to IDL yet. 470 471 [Custom] DOMWindow open(in DOMString url, 472 in DOMString name, 473 in [Optional] DOMString options); 474 475 [Custom] DOMObject showModalDialog(in DOMString url, 476 in [Optional] DOMObject dialogArgs, 477 in [Optional] DOMString featureArgs); 478 479 // window.toString requires special handling 477 // window.toString() requires special handling in V8 480 478 [V8DoNotCheckSignature, DoNotCheckDomainSecurity, Custom, DontEnum] DOMString toString(); 481 479 #endif // defined(V8_BINDING)
Note: See TracChangeset
for help on using the changeset viewer.